11/** Provides classes for working with files and folders. */
22
33import go
4+ private import codeql.util.FileSystem
45
5- /** A file or folder. */
6- abstract class Container extends @container {
7- /**
8- * Gets the absolute, canonical path of this container, using forward slashes
9- * as path separator.
10- *
11- * The path starts with a _root prefix_ followed by zero or more _path
12- * segments_ separated by forward slashes.
13- *
14- * The root prefix is of one of the following forms:
15- *
16- * 1. A single forward slash `/` (Unix-style)
17- * 2. An upper-case drive letter followed by a colon and a forward slash,
18- * such as `C:/` (Windows-style)
19- * 3. Two forward slashes, a computer name, and then another forward slash,
20- * such as `//FileServer/` (UNC-style)
21- *
22- * Path segments are never empty (that is, absolute paths never contain two
23- * contiguous slashes, except as part of a UNC-style root prefix). Also, path
24- * segments never contain forward slashes, and no path segment is of the
25- * form `.` (one dot) or `..` (two dots).
26- *
27- * Note that an absolute path never ends with a forward slash, except if it is
28- * a bare root prefix, that is, the path has no path segments. A container
29- * whose absolute path has no segments is always a `Folder`, not a `File`.
30- */
31- abstract string getAbsolutePath ( ) ;
6+ private module Input implements InputSig {
7+ abstract class ContainerBase extends @container {
8+ abstract string getAbsolutePath ( ) ;
329
33- /**
34- * Gets a URL representing the location of this container.
35- *
36- * For more information see https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls.
37- */
38- abstract string getURL ( ) ;
10+ ContainerBase getParentContainer ( ) { containerparent ( result , this ) }
3911
40- /**
41- * Gets the relative path of this file or folder from the root folder of the
42- * analyzed source location. The relative path of the root folder itself is
43- * the empty string.
44- *
45- * This has no result if the container is outside the source root, that is,
46- * if the root folder is not a reflexive, transitive parent of this container.
47- */
48- string getRelativePath ( ) {
49- exists ( string absPath , string pref |
50- absPath = this .getAbsolutePath ( ) and sourceLocationPrefix ( pref )
51- |
52- absPath = pref and result = ""
53- or
54- absPath = pref .regexpReplaceAll ( "/$" , "" ) + "/" + result and
55- not result .matches ( "/%" )
56- )
12+ string toString ( ) { result = this .getAbsolutePath ( ) }
5713 }
5814
59- /**
60- * Gets the base name of this container including extension, that is, the last
61- * segment of its absolute path, or the empty string if it has no segments.
62- *
63- * Here are some examples of absolute paths and the corresponding base names
64- * (surrounded with quotes to avoid ambiguity):
65- *
66- * <table border="1">
67- * <tr><th>Absolute path</th><th>Base name</th></tr>
68- * <tr><td>"/tmp/tst.go"</td><td>"tst.go"</td></tr>
69- * <tr><td>"C:/Program Files (x86)"</td><td>"Program Files (x86)"</td></tr>
70- * <tr><td>"/"</td><td>""</td></tr>
71- * <tr><td>"C:/"</td><td>""</td></tr>
72- * <tr><td>"D:/"</td><td>""</td></tr>
73- * <tr><td>"//FileServer/"</td><td>""</td></tr>
74- * </table>
75- */
76- string getBaseName ( ) {
77- result = this .getAbsolutePath ( ) .regexpCapture ( ".*/(([^/]*?)(?:\\.([^.]*))?)" , 1 )
15+ class FolderBase extends ContainerBase , @folder {
16+ override string getAbsolutePath ( ) { folders ( this , result ) }
7817 }
7918
80- /**
81- * Gets the extension of this container, that is, the suffix of its base name
82- * after the last dot character, if any.
83- *
84- * In particular,
85- *
86- * - if the name does not include a dot, there is no extension, so this
87- * predicate has no result;
88- * - if the name ends in a dot, the extension is the empty string;
89- * - if the name contains multiple dots, the extension follows the last dot.
90- *
91- * Here are some examples of absolute paths and the corresponding extensions
92- * (surrounded with quotes to avoid ambiguity):
93- *
94- * <table border="1">
95- * <tr><th>Absolute path</th><th>Extension</th></tr>
96- * <tr><td>"/tmp/tst.go"</td><td>"go"</td></tr>
97- * <tr><td>"/tmp/.classpath"</td><td>"classpath"</td></tr>
98- * <tr><td>"/bin/bash"</td><td>not defined</td></tr>
99- * <tr><td>"/tmp/tst2."</td><td>""</td></tr>
100- * <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
101- * </table>
102- */
103- string getExtension ( ) {
104- result = this .getAbsolutePath ( ) .regexpCapture ( ".*/([^/]*?)(\\.([^.]*))?" , 3 )
105- }
106-
107- /**
108- * Gets the stem of this container, that is, the prefix of its base name up to
109- * (but not including) the last dot character if there is one, or the entire
110- * base name if there is not.
111- *
112- * Here are some examples of absolute paths and the corresponding stems
113- * (surrounded with quotes to avoid ambiguity):
114- *
115- * <table border="1">
116- * <tr><th>Absolute path</th><th>Stem</th></tr>
117- * <tr><td>"/tmp/tst.go"</td><td>"tst"</td></tr>
118- * <tr><td>"/tmp/.classpath"</td><td>""</td></tr>
119- * <tr><td>"/bin/bash"</td><td>"bash"</td></tr>
120- * <tr><td>"/tmp/tst2."</td><td>"tst2"</td></tr>
121- * <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
122- * </table>
123- */
124- string getStem ( ) {
125- result = this .getAbsolutePath ( ) .regexpCapture ( ".*/([^/]*?)(?:\\.([^.]*))?" , 1 )
19+ class FileBase extends ContainerBase , @file {
20+ override string getAbsolutePath ( ) { files ( this , result ) }
12621 }
12722
128- /** Gets the parent container of this file or folder, if any. */
129- Container getParentContainer ( ) { containerparent ( result , this ) }
130-
131- /** Gets a file or sub-folder in this container. */
132- Container getAChildContainer ( ) { this = result .getParentContainer ( ) }
133-
134- /** Gets a file in this container. */
135- File getAFile ( ) { result = this .getAChildContainer ( ) }
136-
137- /** Gets the file in this container that has the given `baseName`, if any. */
138- File getFile ( string baseName ) {
139- result = this .getAFile ( ) and
140- result .getBaseName ( ) = baseName
141- }
142-
143- /** Gets a sub-folder in this container. */
144- Folder getAFolder ( ) { result = this .getAChildContainer ( ) }
23+ predicate hasSourceLocationPrefix = sourceLocationPrefix / 1 ;
24+ }
14525
146- /** Gets the sub-folder in this container that has the given `baseName`, if any. */
147- Folder getFolder ( string baseName ) {
148- result = this .getAFolder ( ) and
149- result .getBaseName ( ) = baseName
150- }
26+ private module Impl = Make< Input > ;
15127
152- /**
153- * Gets a textual representation of the path of this container.
154- *
155- * This is the absolute path of the container.
156- */
157- string toString ( ) { result = this .getAbsolutePath ( ) }
158- }
28+ class Container = Impl:: Container ;
15929
16030/** A folder. */
161- class Folder extends Container , @folder {
162- override string getAbsolutePath ( ) { folders ( this , result ) }
163-
31+ class Folder extends Container , Impl:: Folder {
16432 /** Gets the file or subfolder in this folder that has the given `name`, if any. */
16533 Container getChildContainer ( string name ) {
16634 result = this .getAChildContainer ( ) and
@@ -176,19 +44,14 @@ class Folder extends Container, @folder {
17644
17745 /** Gets a subfolder contained in this folder. */
17846 Folder getASubFolder ( ) { result = this .getAChildContainer ( ) }
179-
180- /** Gets the URL of this folder. */
181- override string getURL ( ) { result = "folder://" + this .getAbsolutePath ( ) }
18247}
18348
18449/** A file, including files that have not been extracted but are referred to as locations for errors. */
185- class ExtractedOrExternalFile extends Container , @file , Documentable , ExprParent , GoModExprParent ,
186- DeclParent , ScopeNode
50+ class ExtractedOrExternalFile extends Container , Impl :: File , Documentable , ExprParent ,
51+ GoModExprParent , DeclParent , ScopeNode
18752{
18853 override Location getLocation ( ) { has_location ( this , result ) }
18954
190- override string getAbsolutePath ( ) { files ( this , result ) }
191-
19255 /** Gets the number of lines in this file. */
19356 int getNumberOfLines ( ) { numlines ( this , result , _, _) }
19457
@@ -246,9 +109,6 @@ class ExtractedOrExternalFile extends Container, @file, Documentable, ExprParent
246109
247110 override string toString ( ) { result = Container .super .toString ( ) }
248111
249- /** Gets the URL of this file. */
250- override string getURL ( ) { result = "file://" + this .getAbsolutePath ( ) + ":0:0:0:0" }
251-
252112 /** Gets the `i`th child comment group. */
253113 CommentGroup getCommentGroup ( int i ) { comment_groups ( result , this , i ) }
254114
0 commit comments