44
55import Location
66private import semmle.code.csharp.ExprOrStmtParent
7- private import dotnet
87private import commons.QualifiedName
98
109/**
@@ -14,18 +13,64 @@ private import commons.QualifiedName
1413 * (`NamespaceDeclaration`), a `using` directive (`UsingDirective`), or type
1514 * parameter constraints (`TypeParameterConstraints`).
1615 */
17- class Element extends DotNet:: Element , @element {
18- override string toStringWithTypes ( ) { result = this .toString ( ) }
16+ class Element extends @element {
17+ /** Gets a textual representation of this element. */
18+ cached
19+ string toString ( ) { none ( ) }
20+
21+ /** Gets the file containing this element. */
22+ final File getFile ( ) { result = this .getLocation ( ) .getFile ( ) }
23+
24+ /** Holds if this element is from source code. */
25+ predicate fromSource ( ) { this .getFile ( ) .fromSource ( ) }
26+
27+ /** Holds if this element is from an assembly. */
28+ predicate fromLibrary ( ) { this .getFile ( ) .fromLibrary ( ) }
29+
30+ /**
31+ * Gets the "language" of this program element, as defined by the extension of the filename.
32+ * For example, C# has language "cs", and Visual Basic has language "vb".
33+ */
34+ final string getLanguage ( ) { result = this .getLocation ( ) .getFile ( ) .getExtension ( ) }
35+
36+ /**
37+ * Gets a comma-separated list of the names of the primary CodeQL classes to which this element belongs.
38+ *
39+ * If no primary class can be determined, the result is `"???"`.
40+ */
41+ final string getPrimaryQlClasses ( ) {
42+ result = strictconcat ( this .getAPrimaryQlClass ( ) , "," )
43+ or
44+ not exists ( this .getAPrimaryQlClass ( ) ) and
45+ result = "???"
46+ }
47+
48+ /**
49+ * Gets the name of a primary CodeQL class to which this element belongs.
50+ *
51+ * For most elements, this is simply the most precise syntactic category to
52+ * which they belong; for example, `AddExpr` is a primary class, but
53+ * `BinaryOperation` is not.
54+ *
55+ * If no primary classes match, this predicate has no result. If multiple
56+ * primary classes match, this predicate can have multiple results.
57+ *
58+ * See also `getPrimaryQlClasses`, which is better to use in most cases.
59+ */
60+ string getAPrimaryQlClass ( ) { none ( ) }
61+
62+ /** Gets the full textual representation of this element, including type information. */
63+ string toStringWithTypes ( ) { result = this .toString ( ) }
1964
2065 /**
2166 * Gets the location of this element. Where an element has locations in
2267 * source and assemblies, choose the source location. If there are multiple
2368 * assembly locations, choose only one.
2469 */
25- final override Location getLocation ( ) { result = bestLocation ( this ) }
70+ final Location getLocation ( ) { result = bestLocation ( this ) }
2671
2772 /** Gets a location of this element, including sources and assemblies. */
28- override Location getALocation ( ) { none ( ) }
73+ Location getALocation ( ) { none ( ) }
2974
3075 /** Gets the parent of this element, if any. */
3176 Element getParent ( ) { result .getAChild ( ) = this }
@@ -46,3 +91,96 @@ class Element extends DotNet::Element, @element {
4691 */
4792 int getIndex ( ) { exists ( Element parent | parent .getChild ( result ) = this ) }
4893}
94+
95+ /** An element that has a name. */
96+ class NamedElement extends Element , @named_element {
97+ /** Gets the name of this element. */
98+ cached
99+ string getName ( ) { none ( ) }
100+
101+ /** Holds if this element has name 'name'. */
102+ final predicate hasName ( string name ) { name = this .getName ( ) }
103+
104+ /**
105+ * Gets the fully qualified name of this element, for example the
106+ * fully qualified name of `M` on line 3 is `N.C.M` in
107+ *
108+ * ```csharp
109+ * namespace N {
110+ * class C {
111+ * void M(int i, string s) { }
112+ * }
113+ * }
114+ * ```
115+ */
116+ cached
117+ deprecated final string getQualifiedName ( ) {
118+ exists ( string qualifier , string name | this .hasQualifiedName ( qualifier , name ) |
119+ if qualifier = "" then result = name else result = qualifier + "." + name
120+ )
121+ }
122+
123+ /**
124+ * Gets the fully qualified name of this element, for example the
125+ * fully qualified name of `M` on line 3 is `N.C.M` in
126+ *
127+ * ```csharp
128+ * namespace N {
129+ * class C {
130+ * void M(int i, string s) { }
131+ * }
132+ * }
133+ * ```
134+ *
135+ * Unbound generic types, such as `IList<T>`, are represented as
136+ * ``System.Collections.Generic.IList`1``.
137+ */
138+ cached
139+ final string getFullyQualifiedName ( ) {
140+ exists ( string qualifier , string name | this .hasFullyQualifiedName ( qualifier , name ) |
141+ if qualifier = "" then result = name else result = qualifier + "." + name
142+ )
143+ }
144+
145+ /**
146+ * DEPRECATED: Use `hasFullyQualifiedName` instead.
147+ *
148+ * Holds if this element has the qualified name `qualifier`.`name`.
149+ */
150+ cached
151+ deprecated predicate hasQualifiedName ( string qualifier , string name ) {
152+ qualifier = "" and name = this .getName ( )
153+ }
154+
155+ /** Holds if this element has the fully qualified name `qualifier`.`name`. */
156+ cached
157+ predicate hasFullyQualifiedName ( string qualifier , string name ) {
158+ qualifier = "" and name = this .getName ( )
159+ }
160+
161+ /** Gets a unique string label for this element. */
162+ cached
163+ string getLabel ( ) { none ( ) }
164+
165+ /** Holds if `other` has the same metadata handle in the same assembly. */
166+ predicate matchesHandle ( NamedElement other ) {
167+ exists ( Assembly asm , int handle |
168+ metadata_handle ( this , asm , handle ) and
169+ metadata_handle ( other , asm , handle )
170+ )
171+ }
172+
173+ /**
174+ * Holds if this element was compiled from source code that is also present in the
175+ * database. That is, this element corresponds to another element from source.
176+ */
177+ predicate compiledFromSource ( ) {
178+ not this .fromSource ( ) and
179+ exists ( NamedElement other | other != this |
180+ this .matchesHandle ( other ) and
181+ other .fromSource ( )
182+ )
183+ }
184+
185+ override string toString ( ) { result = this .getName ( ) }
186+ }
0 commit comments