forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFiles.qll
More file actions
151 lines (124 loc) · 4.59 KB
/
Copy pathFiles.qll
File metadata and controls
151 lines (124 loc) · 4.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/** Provides classes for working with files and folders. */
import javascript
private import NodeModuleResolutionImpl
private import codeql.util.FileSystem
private import internal.Locations
private module FsInput implements InputSig {
abstract class ContainerBase extends @container {
abstract string getAbsolutePath();
ContainerBase getParentContainer() { containerparent(result, this) }
string toString() { result = this.getAbsolutePath() }
}
class FolderBase extends ContainerBase, @folder {
override string getAbsolutePath() { folders(this, result) }
}
class FileBase extends ContainerBase, @file {
override string getAbsolutePath() { files(this, result) }
}
predicate hasSourceLocationPrefix = sourceLocationPrefix/1;
}
private module Impl = Make<FsInput>;
class Container = Impl::Container;
/** A folder. */
class Folder extends Container, Impl::Folder {
/** Gets the file or subfolder in this folder that has the given `name`, if any. */
Container getChildContainer(string name) {
result = this.getAChildContainer() and
result.getBaseName() = name
}
/** Gets the file in this folder that has the given `stem` and `extension`, if any. */
File getFile(string stem, string extension) {
result = this.getAChildContainer() and
result.getStem() = stem and
result.getExtension() = extension
}
/** Like `getFile` except `d.ts` is treated as a single extension. */
private File getFileLongExtension(string stem, string extension) {
not (stem.matches("%.d") and extension = "ts") and
result = this.getFile(stem, extension)
or
extension = "d.ts" and
result = this.getFile(stem + ".d", "ts")
}
/**
* Gets the file in this folder that has the given `stem` and any of the supported JavaScript extensions.
*
* If there are multiple such files, the one with the "best" extension is chosen based on a
* prioritized list of file extensions.
*
* `js` files are given less preference than files that compile to `js`, to ensure we pick the
* original source file rather than its compiled output.
*
* HTML files will not be found by this method.
*/
File getJavaScriptFile(string stem) {
result =
min(int p, string ext |
p = getFileExtensionPriority(ext)
|
this.getFileLongExtension(stem, ext) order by p
)
}
/** Gets a subfolder contained in this folder. */
Folder getASubFolder() { result = this.getAChildContainer() }
}
/** A file. */
class File extends Container, Impl::File {
/**
* Gets the location of this file.
*
* Note that files have special locations starting and ending at line zero, column zero.
*/
DbLocation getLocation() { result = getLocatableLocation(this) }
/** Gets the number of lines in this file. */
int getNumberOfLines() { result = sum(int loc | numlines(this, loc, _, _) | loc) }
/** Gets the number of lines containing code in this file. */
int getNumberOfLinesOfCode() { result = sum(int loc | numlines(this, _, loc, _) | loc) }
/** Gets the number of lines containing comments in this file. */
int getNumberOfLinesOfComments() { result = sum(int loc | numlines(this, _, _, loc) | loc) }
/** Gets a toplevel piece of JavaScript code in this file. */
TopLevel getATopLevel() { result.getFile() = this }
/**
* Holds if line number `lineno` of this file is indented to depth `d`
* using character `c`.
*
* This predicate only holds for lines that belong to JavaScript code that
* start with one or more occurrences of the same whitespace character,
* followed by at least one non-whitespace character.
*
* It does not hold for lines that do not start with a whitespace character,
* or for lines starting with a string of different whitespace characters
* (for instance, a mix of tabs and spaces).
*/
predicate hasIndentation(int lineno, string c, int d) { indentation(this, lineno, c, d) }
/**
* Gets the type of this file.
*/
FileType getFileType() { filetype(this, result) }
}
/**
* A file type.
*/
class FileType extends string {
FileType() { this = ["javascript", "html", "typescript", "json", "yaml"] }
/**
* Holds if this is the JavaScript file type.
*/
predicate isJavaScript() { this = "javascript" }
/**
* Holds if this is the HTML file type.
*/
predicate isHtml() { this = "html" }
/**
* Holds if this is the TypeScript file type.
*/
predicate isTypeScript() { this = "typescript" }
/**
* Holds if this is the JSON file type.
*/
predicate isJson() { this = "json" }
/**
* Holds if this is the YAML file type.
*/
predicate isYaml() { this = "yaml" }
}