Skip to content

Commit 8fbe62c

Browse files
committed
Swift: Implement getExtension and getStem
1 parent 2683e40 commit 8fbe62c

File tree

1 file changed

+56
-3
lines changed
  • swift/ql/lib/codeql/swift/elements

1 file changed

+56
-3
lines changed

swift/ql/lib/codeql/swift/elements/File.qll

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,64 @@ class File extends Generated::File {
1515
/** Gets the URL of this file. */
1616
string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
1717

18-
/** Gets the base name of this file. */
19-
string getBaseName() {
20-
result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
18+
/**
19+
* Holds if either,
20+
* - `part` is the base name of this container and `i = 1`, or
21+
* - `part` is the stem of this container and `i = 2`, or
22+
* - `part` is the extension of this container and `i = 3`.
23+
*/
24+
cached
25+
private predicate splitAbsolutePath(string part, int i) {
26+
part = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", i)
2127
}
2228

29+
/** Gets the base name of this file. */
30+
string getBaseName() { this.splitAbsolutePath(result, 1) }
31+
32+
/**
33+
* Gets the extension of this container, that is, the suffix of its base name
34+
* after the last dot character, if any.
35+
*
36+
* In particular,
37+
*
38+
* - if the name does not include a dot, there is no extension, so this
39+
* predicate has no result;
40+
* - if the name ends in a dot, the extension is the empty string;
41+
* - if the name contains multiple dots, the extension follows the last dot.
42+
*
43+
* Here are some examples of absolute paths and the corresponding extensions
44+
* (surrounded with quotes to avoid ambiguity):
45+
*
46+
* <table border="1">
47+
* <tr><th>Absolute path</th><th>Extension</th></tr>
48+
* <tr><td>"/tmp/tst.txt"</td><td>"txt"</td></tr>
49+
* <tr><td>"/tmp/.classpath"</td><td>"classpath"</td></tr>
50+
* <tr><td>"/bin/bash"</td><td>not defined</td></tr>
51+
* <tr><td>"/tmp/tst2."</td><td>""</td></tr>
52+
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
53+
* </table>
54+
*/
55+
string getExtension() { this.splitAbsolutePath(result, 3) }
56+
57+
/**
58+
* Gets the stem of this container, that is, the prefix of its base name up to
59+
* (but not including) the last dot character if there is one, or the entire
60+
* base name if there is not.
61+
*
62+
* Here are some examples of absolute paths and the corresponding stems
63+
* (surrounded with quotes to avoid ambiguity):
64+
*
65+
* <table border="1">
66+
* <tr><th>Absolute path</th><th>Stem</th></tr>
67+
* <tr><td>"/tmp/tst.txt"</td><td>"tst"</td></tr>
68+
* <tr><td>"/tmp/.classpath"</td><td>""</td></tr>
69+
* <tr><td>"/bin/bash"</td><td>"bash"</td></tr>
70+
* <tr><td>"/tmp/tst2."</td><td>"tst2"</td></tr>
71+
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
72+
* </table>
73+
*/
74+
string getStem() { this.splitAbsolutePath(result, 2) }
75+
2376
/**
2477
* Gets the number of lines containing code in this file. This value
2578
* is approximate.

0 commit comments

Comments
 (0)