Skip to content

Commit bd5ae88

Browse files
committed
Ruby: Move FileSystem.qll implementation into shared util pack
1 parent 8ed99bc commit bd5ae88

File tree

2 files changed

+228
-156
lines changed

2 files changed

+228
-156
lines changed
Lines changed: 16 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -1,177 +1,37 @@
11
/** Provides classes for working with files and folders. */
22

33
private import codeql.Locations
4+
private import codeql.util.FileSystem
45

5-
/** A file or folder. */
6-
abstract class Container extends @container {
7-
/** Gets a file or sub-folder in this container. */
8-
Container getAChildContainer() { this = result.getParentContainer() }
6+
private module Input implements InputSig {
7+
abstract class ContainerBase extends @container {
8+
abstract string getAbsolutePath();
99

10-
/** Gets a file in this container. */
11-
File getAFile() { result = this.getAChildContainer() }
10+
ContainerBase getParentContainer() { containerparent(result, this) }
1211

13-
/** Gets a sub-folder in this container. */
14-
Folder getAFolder() { result = this.getAChildContainer() }
15-
16-
/**
17-
* Gets the absolute, canonical path of this container, using forward slashes
18-
* as path separator.
19-
*
20-
* The path starts with a _root prefix_ followed by zero or more _path
21-
* segments_ separated by forward slashes.
22-
*
23-
* The root prefix is of one of the following forms:
24-
*
25-
* 1. A single forward slash `/` (Unix-style)
26-
* 2. An upper-case drive letter followed by a colon and a forward slash,
27-
* such as `C:/` (Windows-style)
28-
* 3. Two forward slashes, a computer name, and then another forward slash,
29-
* such as `//FileServer/` (UNC-style)
30-
*
31-
* Path segments are never empty (that is, absolute paths never contain two
32-
* contiguous slashes, except as part of a UNC-style root prefix). Also, path
33-
* segments never contain forward slashes, and no path segment is of the
34-
* form `.` (one dot) or `..` (two dots).
35-
*
36-
* Note that an absolute path never ends with a forward slash, except if it is
37-
* a bare root prefix, that is, the path has no path segments. A container
38-
* whose absolute path has no segments is always a `Folder`, not a `File`.
39-
*/
40-
abstract string getAbsolutePath();
41-
42-
/**
43-
* Gets the base name of this container including extension, that is, the last
44-
* segment of its absolute path, or the empty string if it has no segments.
45-
*
46-
* Here are some examples of absolute paths and the corresponding base names
47-
* (surrounded with quotes to avoid ambiguity):
48-
*
49-
* <table border="1">
50-
* <tr><th>Absolute path</th><th>Base name</th></tr>
51-
* <tr><td>"/tmp/tst.go"</td><td>"tst.go"</td></tr>
52-
* <tr><td>"C:/Program Files (x86)"</td><td>"Program Files (x86)"</td></tr>
53-
* <tr><td>"/"</td><td>""</td></tr>
54-
* <tr><td>"C:/"</td><td>""</td></tr>
55-
* <tr><td>"D:/"</td><td>""</td></tr>
56-
* <tr><td>"//FileServer/"</td><td>""</td></tr>
57-
* </table>
58-
*/
59-
string getBaseName() {
60-
result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
61-
}
62-
63-
/**
64-
* Gets the extension of this container, that is, the suffix of its base name
65-
* after the last dot character, if any.
66-
*
67-
* In particular,
68-
*
69-
* - if the name does not include a dot, there is no extension, so this
70-
* predicate has no result;
71-
* - if the name ends in a dot, the extension is the empty string;
72-
* - if the name contains multiple dots, the extension follows the last dot.
73-
*
74-
* Here are some examples of absolute paths and the corresponding extensions
75-
* (surrounded with quotes to avoid ambiguity):
76-
*
77-
* <table border="1">
78-
* <tr><th>Absolute path</th><th>Extension</th></tr>
79-
* <tr><td>"/tmp/tst.go"</td><td>"go"</td></tr>
80-
* <tr><td>"/tmp/.classpath"</td><td>"classpath"</td></tr>
81-
* <tr><td>"/bin/bash"</td><td>not defined</td></tr>
82-
* <tr><td>"/tmp/tst2."</td><td>""</td></tr>
83-
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
84-
* </table>
85-
*/
86-
string getExtension() {
87-
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
12+
string toString() { result = this.getAbsolutePath() }
8813
}
8914

90-
/** Gets the file in this container that has the given `baseName`, if any. */
91-
File getFile(string baseName) {
92-
result = this.getAFile() and
93-
result.getBaseName() = baseName
15+
class FolderBase extends ContainerBase, @folder {
16+
override string getAbsolutePath() { folders(this, result) }
9417
}
9518

96-
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
97-
Folder getFolder(string baseName) {
98-
result = this.getAFolder() and
99-
result.getBaseName() = baseName
100-
}
101-
102-
/** Gets the parent container of this file or folder, if any. */
103-
Container getParentContainer() { containerparent(result, this) }
104-
105-
/**
106-
* Gets the relative path of this file or folder from the root folder of the
107-
* analyzed source location. The relative path of the root folder itself is
108-
* the empty string.
109-
*
110-
* This has no result if the container is outside the source root, that is,
111-
* if the root folder is not a reflexive, transitive parent of this container.
112-
*/
113-
string getRelativePath() {
114-
exists(string absPath, string pref |
115-
absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
116-
|
117-
absPath = pref and result = ""
118-
or
119-
absPath = pref.regexpReplaceAll("/$", "") + "/" + result and
120-
not result.matches("/%")
121-
)
19+
class FileBase extends ContainerBase, @file {
20+
override string getAbsolutePath() { files(this, result) }
12221
}
12322

124-
/**
125-
* Gets the stem of this container, that is, the prefix of its base name up to
126-
* (but not including) the last dot character if there is one, or the entire
127-
* base name if there is not.
128-
*
129-
* Here are some examples of absolute paths and the corresponding stems
130-
* (surrounded with quotes to avoid ambiguity):
131-
*
132-
* <table border="1">
133-
* <tr><th>Absolute path</th><th>Stem</th></tr>
134-
* <tr><td>"/tmp/tst.go"</td><td>"tst"</td></tr>
135-
* <tr><td>"/tmp/.classpath"</td><td>""</td></tr>
136-
* <tr><td>"/bin/bash"</td><td>"bash"</td></tr>
137-
* <tr><td>"/tmp/tst2."</td><td>"tst2"</td></tr>
138-
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
139-
* </table>
140-
*/
141-
string getStem() {
142-
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
143-
}
23+
predicate hasSourceLocationPrefix = sourceLocationPrefix/1;
24+
}
14425

145-
/**
146-
* Gets a URL representing the location of this container.
147-
*
148-
* For more information see https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls.
149-
*/
150-
abstract string getURL();
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-
164-
/** Gets the URL of this folder. */
165-
override string getURL() { result = "folder://" + this.getAbsolutePath() }
166-
}
31+
class Folder extends Container, Impl::Folder { }
16732

16833
/** A file. */
169-
class File extends Container, @file {
170-
override string getAbsolutePath() { files(this, result) }
171-
172-
/** Gets the URL of this file. */
173-
override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
174-
34+
class File extends Container, Impl::File {
17535
/** Holds if this file was extracted from ordinary source code. */
17636
predicate fromSource() { any() }
17737
}

0 commit comments

Comments
 (0)