Skip to content

Commit bd1de17

Browse files
authored
Merge pull request #15887 from michaelnebel/csharp/qualifiedname
C#: Fully qualified name.
2 parents 7b2dc32 + 10d96ee commit bd1de17

File tree

23 files changed

+107
-155
lines changed

23 files changed

+107
-155
lines changed

csharp/ql/integration-tests/all-platforms/diag_recursive_generics/Types.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ import csharp
22

33
from Class c
44
where c.fromSource()
5-
select c, c.getBaseClass().getFullyQualifiedName()
5+
select c, c.getBaseClass().getFullyQualifiedNameDebug()

csharp/ql/lib/semmle/code/csharp/Element.qll

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ class NamedElement extends Element, @named_element {
102102
final predicate hasName(string name) { name = this.getName() }
103103

104104
/**
105+
* DEPRECATED: Use `hasFullyQualifiedName` instead.
106+
*
105107
* Gets the fully qualified name of this element, for example the
106108
* fully qualified name of `M` on line 3 is `N.C.M` in
107109
*
@@ -112,15 +114,23 @@ class NamedElement extends Element, @named_element {
112114
* }
113115
* }
114116
* ```
117+
*
118+
* Unbound generic types, such as `IList<T>`, are represented as
119+
* ``System.Collections.Generic.IList`1``.
115120
*/
116-
cached
117-
deprecated final string getQualifiedName() {
118-
exists(string qualifier, string name | this.hasQualifiedName(qualifier, name) |
121+
deprecated final string getFullyQualifiedName() {
122+
exists(string qualifier, string name | this.hasFullyQualifiedName(qualifier, name) |
119123
if qualifier = "" then result = name else result = qualifier + "." + name
120124
)
121125
}
122126

123127
/**
128+
* INTERNAL: Do not use.
129+
*
130+
* This is intended for DEBUG ONLY.
131+
* Constructing the fully qualified name for all elements in a large codebase
132+
* puts severe stress on the string pool.
133+
*
124134
* Gets the fully qualified name of this element, for example the
125135
* fully qualified name of `M` on line 3 is `N.C.M` in
126136
*
@@ -135,23 +145,14 @@ class NamedElement extends Element, @named_element {
135145
* Unbound generic types, such as `IList<T>`, are represented as
136146
* ``System.Collections.Generic.IList`1``.
137147
*/
138-
cached
139-
final string getFullyQualifiedName() {
148+
bindingset[this]
149+
pragma[inline_late]
150+
final string getFullyQualifiedNameDebug() {
140151
exists(string qualifier, string name | this.hasFullyQualifiedName(qualifier, name) |
141152
if qualifier = "" then result = name else result = qualifier + "." + name
142153
)
143154
}
144155

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-
155156
/** Holds if this element has the fully qualified name `qualifier`.`name`. */
156157
cached
157158
predicate hasFullyQualifiedName(string qualifier, string name) {

csharp/ql/lib/semmle/code/csharp/Member.qll

Lines changed: 6 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,11 @@ class Declaration extends NamedElement, @declaration {
7171

7272
override string toString() { result = this.getName() }
7373

74-
deprecated override predicate hasQualifiedName(string qualifier, string name) {
75-
QualifiedName<QualifiedNameInput>::hasQualifiedName(this, qualifier, name)
76-
}
77-
7874
override predicate hasFullyQualifiedName(string qualifier, string name) {
7975
QualifiedName<FullyQualifiedNameInput>::hasQualifiedName(this, qualifier, name)
8076
}
8177

8278
/**
83-
* DEPRECATED: Use `getFullyQualifiedNameWithTypes` instead.
84-
*
8579
* Gets the fully qualified name of this declaration, including types, for example
8680
* the fully qualified name with types of `M` on line 3 is `N.C.M(int, string)` in
8781
*
@@ -93,33 +87,13 @@ class Declaration extends NamedElement, @declaration {
9387
* }
9488
* ```
9589
*/
96-
deprecated string getQualifiedNameWithTypes() {
97-
exists(string qual |
98-
qual = this.getDeclaringType().getQualifiedName() and
90+
deprecated string getFullyQualifiedNameWithTypes() {
91+
exists(string fullqual, string qual, string name |
92+
this.getDeclaringType().hasFullyQualifiedName(qual, name) and
93+
fullqual = getQualifiedName(qual, name) and
9994
if this instanceof NestedType
100-
then result = qual + "+" + this.toStringWithTypes()
101-
else result = qual + "." + this.toStringWithTypes()
102-
)
103-
}
104-
105-
/**
106-
* Gets the fully qualified name of this declaration, including types, for example
107-
* the fully qualified name with types of `M` on line 3 is `N.C.M(int, string)` in
108-
*
109-
* ```csharp
110-
* namespace N {
111-
* class C {
112-
* void M(int i, string s) { }
113-
* }
114-
* }
115-
* ```
116-
*/
117-
string getFullyQualifiedNameWithTypes() {
118-
exists(string qual |
119-
qual = this.getDeclaringType().getFullyQualifiedName() and
120-
if this instanceof NestedType
121-
then result = qual + "+" + this.toStringWithTypes()
122-
else result = qual + "." + this.toStringWithTypes()
95+
then result = fullqual + "+" + this.toStringWithTypes()
96+
else result = fullqual + "." + this.toStringWithTypes()
12397
)
12498
}
12599

@@ -263,17 +237,6 @@ class Member extends Modifiable, @member {
263237
/** Gets an access to this member. */
264238
MemberAccess getAnAccess() { result.getTarget() = this }
265239

266-
/**
267-
* DEPRECATED: Use `hasFullyQualifiedName` instead.
268-
*
269-
* Holds if this member has name `name` and is defined in type `type`
270-
* with namespace `namespace`.
271-
*/
272-
cached
273-
deprecated final predicate hasQualifiedName(string namespace, string type, string name) {
274-
QualifiedName<QualifiedNameInput>::hasQualifiedName(this, namespace, type, name)
275-
}
276-
277240
/**
278241
* Holds if this member has name `name` and is defined in type `type`
279242
* with namespace `namespace`.

csharp/ql/lib/semmle/code/csharp/Namespace.qll

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,6 @@ class Namespace extends TypeContainer, Declaration, @namespace {
3838
parent_namespace(result, this)
3939
}
4040

41-
/**
42-
* Holds if this namespace has the qualified name `qualifier`.`name`.
43-
*
44-
* For example if the qualified name is `System.Collections.Generic`, then
45-
* `qualifier`=`System.Collections` and `name`=`Generic`.
46-
*/
47-
deprecated override predicate hasQualifiedName(string qualifier, string name) {
48-
namespaceHasQualifiedName(this, qualifier, name)
49-
}
50-
5141
/**
5242
* Holds if this namespace has the qualified name `qualifier`.`name`.
5343
*

csharp/ql/lib/semmle/code/csharp/commons/QualifiedName.qll

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,28 @@ predicate splitQualifiedName(string qualifiedName, string qualifier, string name
219219
name = qualifiedName
220220
)
221221
}
222+
223+
/**
224+
* INTERNAL: Do not use.
225+
*
226+
* Gets the fully qualified name of this declaration, including types, for example
227+
* the fully qualified name with types of `M` on line 3 is `N.C.M(int, string)` in
228+
*
229+
* ```csharp
230+
* namespace N {
231+
* class C {
232+
* void M(int i, string s) { }
233+
* }
234+
* }
235+
* ```
236+
*/
237+
bindingset[d]
238+
string getFullyQualifiedNameWithTypes(Declaration d) {
239+
exists(string fullqual, string qual, string name |
240+
d.getDeclaringType().hasFullyQualifiedName(qual, name) and
241+
fullqual = getQualifiedName(qual, name) and
242+
if d instanceof NestedType
243+
then result = fullqual + "+" + d.toStringWithTypes()
244+
else result = fullqual + "." + d.toStringWithTypes()
245+
)
246+
}

csharp/ql/lib/semmle/code/csharp/dataflow/SSA.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ module Ssa {
120120
result = prefix + "." + this.getAssignable()
121121
|
122122
if f.(Modifiable).isStatic()
123-
then prefix = f.getDeclaringType().getFullyQualifiedName()
123+
then prefix = f.getDeclaringType().getName()
124124
else prefix = "this"
125125
)
126126
}

csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*/
44

55
private import csharp
6+
private import semmle.code.csharp.commons.QualifiedName
67
private import semmle.code.csharp.frameworks.system.linq.Expressions
78
private import codeql.dataflow.internal.FlowSummaryImpl
89
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
@@ -42,10 +43,18 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CsharpDataFlow>
4243
string encodeContent(ContentSet c, string arg) {
4344
c = TElementContent() and result = "Element" and arg = ""
4445
or
45-
exists(Field f | c = TFieldContent(f) and result = "Field" and arg = f.getFullyQualifiedName())
46+
exists(Field f, string qualifier, string name |
47+
c = TFieldContent(f) and
48+
f.hasFullyQualifiedName(qualifier, name) and
49+
arg = getQualifiedName(qualifier, name) and
50+
result = "Field"
51+
)
4652
or
47-
exists(Property p |
48-
c = TPropertyContent(p) and result = "Property" and arg = p.getFullyQualifiedName()
53+
exists(Property p, string qualifier, string name |
54+
c = TPropertyContent(p) and
55+
p.hasFullyQualifiedName(qualifier, name) and
56+
arg = getQualifiedName(qualifier, name) and
57+
result = "Property"
4958
)
5059
or
5160
exists(SyntheticField f |

csharp/ql/lib/semmle/code/csharp/security/dataflow/ExternalAPIsQuery.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,13 @@ class ExternalApiUsedWithUntrustedData extends TExternalApi {
139139

140140
/** Gets a textual representation of this element. */
141141
string toString() {
142-
exists(Callable m, int index, string indexString |
142+
exists(Callable m, int index, string indexString, string qualifier, string name |
143143
if index = -1 then indexString = "qualifier" else indexString = "param " + index
144144
|
145145
this = TExternalApiParameter(m, index) and
146+
m.getDeclaringType().hasFullyQualifiedName(qualifier, name) and
146147
result =
147-
m.getDeclaringType().getFullyQualifiedName() + "." + m.toStringWithTypes() + " [" +
148-
indexString + "]"
148+
getQualifiedName(qualifier, name) + "." + m.toStringWithTypes() + " [" + indexString + "]"
149149
)
150150
}
151151
}
Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import csharp
2-
import semmle.code.csharp.commons.QualifiedName
32

4-
from Attributable element, Attribute attribute, string qualifier, string name
3+
from Attributable element, Attribute attribute
54
where
65
attribute = element.getAnAttribute() and
7-
(attribute.fromSource() or element.(Assembly).getName() in ["attributes", "Assembly1"]) and
8-
attribute.getType().hasFullyQualifiedName(qualifier, name)
9-
select element, attribute, getQualifiedName(qualifier, name)
6+
(attribute.fromSource() or element.(Assembly).getName() in ["attributes", "Assembly1"])
7+
select element, attribute, attribute.getType().getFullyQualifiedNameDebug()

csharp/ql/test/library-tests/constructors/Destructors1.ql

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
*/
44

55
import csharp
6-
import semmle.code.csharp.commons.QualifiedName
76

87
from Destructor c, string qualifier, string name
98
where
109
c.getDeclaringType().hasFullyQualifiedName(qualifier, name) and
1110
qualifier = "Constructors" and
1211
name = "Class"
13-
select c, c.getDeclaringType().getFullyQualifiedName()
12+
select c, c.getDeclaringType().getFullyQualifiedNameDebug()

0 commit comments

Comments
 (0)