@@ -219,3 +219,140 @@ module Make<InputSig Input> {
219219 override string getURL ( ) { result = "file://" + this .getAbsolutePath ( ) + ":0:0:0:0" }
220220 }
221221}
222+
223+ /** A file. */
224+ signature class FileSig {
225+ /**
226+ * Gets the absolute, canonical path of this container, using forward slashes
227+ * as path separator.
228+ *
229+ * The path starts with a _root prefix_ followed by zero or more _path
230+ * segments_ separated by forward slashes.
231+ *
232+ * The root prefix is of one of the following forms:
233+ *
234+ * 1. A single forward slash `/` (Unix-style)
235+ * 2. An upper-case drive letter followed by a colon and a forward slash,
236+ * such as `C:/` (Windows-style)
237+ * 3. Two forward slashes, a computer name, and then another forward slash,
238+ * such as `//FileServer/` (UNC-style)
239+ *
240+ * Path segments are never empty (that is, absolute paths never contain two
241+ * contiguous slashes, except as part of a UNC-style root prefix). Also, path
242+ * segments never contain forward slashes, and no path segment is of the
243+ * form `.` (one dot) or `..` (two dots).
244+ *
245+ * Note that an absolute path never ends with a forward slash, except if it is
246+ * a bare root prefix, that is, the path has no path segments. A container
247+ * whose absolute path has no segments is always a `Folder`, not a `File`.
248+ */
249+ string getAbsolutePath ( ) ;
250+
251+ /**
252+ * Gets the base name of this container including extension, that is, the last
253+ * segment of its absolute path, or the empty string if it has no segments.
254+ *
255+ * Here are some examples of absolute paths and the corresponding base names
256+ * (surrounded with quotes to avoid ambiguity):
257+ *
258+ * <table border="1">
259+ * <tr><th>Absolute path</th><th>Base name</th></tr>
260+ * <tr><td>"/tmp/tst.txt"</td><td>"tst.txt"</td></tr>
261+ * <tr><td>"C:/Program Files (x86)"</td><td>"Program Files (x86)"</td></tr>
262+ * <tr><td>"/"</td><td>""</td></tr>
263+ * <tr><td>"C:/"</td><td>""</td></tr>
264+ * <tr><td>"D:/"</td><td>""</td></tr>
265+ * <tr><td>"//FileServer/"</td><td>""</td></tr>
266+ * </table>
267+ */
268+ string getBaseName ( ) ;
269+
270+ /**
271+ * Gets the extension of this container, that is, the suffix of its base name
272+ * after the last dot character, if any.
273+ *
274+ * In particular,
275+ *
276+ * - if the name does not include a dot, there is no extension, so this
277+ * predicate has no result;
278+ * - if the name ends in a dot, the extension is the empty string;
279+ * - if the name contains multiple dots, the extension follows the last dot.
280+ *
281+ * Here are some examples of absolute paths and the corresponding extensions
282+ * (surrounded with quotes to avoid ambiguity):
283+ *
284+ * <table border="1">
285+ * <tr><th>Absolute path</th><th>Extension</th></tr>
286+ * <tr><td>"/tmp/tst.txt"</td><td>"txt"</td></tr>
287+ * <tr><td>"/tmp/.classpath"</td><td>"classpath"</td></tr>
288+ * <tr><td>"/bin/bash"</td><td>not defined</td></tr>
289+ * <tr><td>"/tmp/tst2."</td><td>""</td></tr>
290+ * <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
291+ * </table>
292+ */
293+ string getExtension ( ) ;
294+
295+ /**
296+ * Gets the relative path of this file or folder from the root folder of the
297+ * analyzed source location. The relative path of the root folder itself is
298+ * the empty string.
299+ *
300+ * This has no result if the container is outside the source root, that is,
301+ * if the root folder is not a reflexive, transitive parent of this container.
302+ */
303+ string getRelativePath ( ) ;
304+
305+ /**
306+ * Gets the stem of this container, that is, the prefix of its base name up to
307+ * (but not including) the last dot character if there is one, or the entire
308+ * base name if there is not.
309+ *
310+ * Here are some examples of absolute paths and the corresponding stems
311+ * (surrounded with quotes to avoid ambiguity):
312+ *
313+ * <table border="1">
314+ * <tr><th>Absolute path</th><th>Stem</th></tr>
315+ * <tr><td>"/tmp/tst.txt"</td><td>"tst"</td></tr>
316+ * <tr><td>"/tmp/.classpath"</td><td>""</td></tr>
317+ * <tr><td>"/bin/bash"</td><td>"bash"</td></tr>
318+ * <tr><td>"/tmp/tst2."</td><td>"tst2"</td></tr>
319+ * <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
320+ * </table>
321+ */
322+ string getStem ( ) ;
323+
324+ /**
325+ * Gets a URL representing the location of this container.
326+ *
327+ * For more information see https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/#providing-urls.
328+ */
329+ string getURL ( ) ;
330+
331+ /**
332+ * Gets a textual representation of the path of this container.
333+ *
334+ * This is the absolute path of the container.
335+ */
336+ string toString ( ) ;
337+ }
338+
339+ /**
340+ * Provides shared predicates related to contextual queries in the code viewer.
341+ */
342+ module IdeContextual< FileSig File> {
343+ /**
344+ * Returns the `File` matching the given source file name as encoded by the VS
345+ * Code extension.
346+ */
347+ File getFileBySourceArchiveName ( string name ) {
348+ // The name provided for a file in the source archive by the VS Code extension
349+ // has some differences from the absolute path in the database:
350+ // 1. colons are replaced by underscores
351+ // 2. there's a leading slash, even for Windows paths: "C:/foo/bar" ->
352+ // "/C_/foo/bar"
353+ // 3. double slashes in UNC prefixes are replaced with a single slash
354+ // We can handle 2 and 3 together by unconditionally adding a leading slash
355+ // before replacing double slashes.
356+ name = ( "/" + result .getAbsolutePath ( ) .replaceAll ( ":" , "_" ) ) .replaceAll ( "//" , "/" )
357+ }
358+ }
0 commit comments