@@ -15,11 +15,64 @@ class File extends Generated::File {
15
15
/** Gets the URL of this file. */
16
16
string getURL ( ) { result = "file://" + this .getAbsolutePath ( ) + ":0:0:0:0" }
17
17
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 )
21
27
}
22
28
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
+
23
76
/**
24
77
* Gets the number of lines containing code in this file. This value
25
78
* is approximate.
0 commit comments