1
1
/** Provides classes for working with files and folders. */
2
2
3
3
import go
4
+ private import codeql.util.FileSystem
4
5
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 ( ) ;
32
9
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 ) }
39
11
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 ( ) }
57
13
}
58
14
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 ) }
78
17
}
79
18
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 ) }
126
21
}
127
22
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
+ }
145
25
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 > ;
151
27
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 ;
159
29
160
30
/** A folder. */
161
- class Folder extends Container , @folder {
162
- override string getAbsolutePath ( ) { folders ( this , result ) }
163
-
31
+ class Folder extends Container , Impl:: Folder {
164
32
/** Gets the file or subfolder in this folder that has the given `name`, if any. */
165
33
Container getChildContainer ( string name ) {
166
34
result = this .getAChildContainer ( ) and
@@ -176,19 +44,14 @@ class Folder extends Container, @folder {
176
44
177
45
/** Gets a subfolder contained in this folder. */
178
46
Folder getASubFolder ( ) { result = this .getAChildContainer ( ) }
179
-
180
- /** Gets the URL of this folder. */
181
- override string getURL ( ) { result = "folder://" + this .getAbsolutePath ( ) }
182
47
}
183
48
184
49
/** 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
187
52
{
188
53
override Location getLocation ( ) { has_location ( this , result ) }
189
54
190
- override string getAbsolutePath ( ) { files ( this , result ) }
191
-
192
55
/** Gets the number of lines in this file. */
193
56
int getNumberOfLines ( ) { numlines ( this , result , _, _) }
194
57
@@ -246,9 +109,6 @@ class ExtractedOrExternalFile extends Container, @file, Documentable, ExprParent
246
109
247
110
override string toString ( ) { result = Container .super .toString ( ) }
248
111
249
- /** Gets the URL of this file. */
250
- override string getURL ( ) { result = "file://" + this .getAbsolutePath ( ) + ":0:0:0:0" }
251
-
252
112
/** Gets the `i`th child comment group. */
253
113
CommentGroup getCommentGroup ( int i ) { comment_groups ( result , this , i ) }
254
114
0 commit comments