-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathElement.qll
More file actions
120 lines (101 loc) · 3.63 KB
/
Element.qll
File metadata and controls
120 lines (101 loc) · 3.63 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
/**
* Provides the .Net `Element` class.
*/
private import DotNet
import semmle.code.csharp.Location
/**
* A .Net program element.
*/
class Element extends @dotnet_element {
/** Gets a textual representation of this element. */
cached
string toString() { none() }
/** Gets the location of this element. */
Location getLocation() { none() }
/**
* Gets a location of this element, which can include locations in
* both DLLs and source files.
*/
Location getALocation() { none() }
/** Gets the file containing this element. */
final File getFile() { result = this.getLocation().getFile() }
/** Holds if this element is from source code. */
predicate fromSource() { this.getFile().fromSource() }
/** Holds if this element is from an assembly. */
predicate fromLibrary() { this.getFile().fromLibrary() }
/**
* Gets the "language" of this program element, as defined by the extension of the filename.
* For example, C# has language "cs", and Visual Basic has language "vb".
*/
final string getLanguage() { result = getLocation().getFile().getExtension() }
/** Gets the full textual representation of this element, including type information. */
string toStringWithTypes() { result = this.toString() }
/**
* Gets the name of a primary CodeQL class to which this element belongs.
*
* For most elements, this is simply the most precise syntactic category to
* which they belong; for example, `AddExpr` is a primary class, but
* `BinaryOperation` is not.
*
* This predicate always has a result. If no primary class can be
* determined, the result is `"???"`. If multiple primary classes match,
* this predicate can have multiple results.
*/
string getAPrimaryQlClass() { result = "???" }
}
/** An element that has a name. */
class NamedElement extends Element, @dotnet_named_element {
/** Gets the name of this element. */
string getName() { none() }
/** Holds if this element has name 'name'. */
final predicate hasName(string name) { name = getName() }
/**
* Gets the fully qualified name of this element, for example the
* fully qualified name of `M` on line 3 is `N.C.M` in
*
* ```csharp
* namespace N {
* class C {
* void M(int i, string s) { }
* }
* }
* ```
*/
final string getQualifiedName() {
exists(string qualifier, string name | this.hasQualifiedName(qualifier, name) |
if qualifier = "" then result = name else result = qualifier + "." + name
)
}
/**
* Holds if this element has qualified name `qualifiedName`, for example
* `System.Console.WriteLine`.
*/
final predicate hasQualifiedName(string qualifiedName) { qualifiedName = this.getQualifiedName() }
/** Holds if this element has the qualified name `qualifier`.`name`. */
cached
predicate hasQualifiedName(string qualifier, string name) {
qualifier = "" and name = this.getName()
}
/** Gets a unique string label for this element. */
cached
string getLabel() { none() }
/** Holds if `other` has the same metadata handle in the same assembly. */
predicate matchesHandle(NamedElement other) {
exists(Assembly asm, int handle |
metadata_handle(this, asm, handle) and
metadata_handle(other, asm, handle)
)
}
/**
* Holds if this element was compiled from source code that is also present in the
* database. That is, this element corresponds to another element from source.
*/
predicate compiledFromSource() {
not this.fromSource() and
exists(NamedElement other | other != this |
this.matchesHandle(other) and
other.fromSource()
)
}
override string toString() { result = this.getName() }
}