Skip to content

Commit 66dc550

Browse files
committed
C#: Deprecate {get,has}QualifiedName and replace with {get,has}FullyQualifiedName
1 parent 94d08aa commit 66dc550

15 files changed

+151
-43
lines changed

csharp/ql/lib/semmle/code/cil/Declaration.qll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,21 @@ class Declaration extends DotNet::Declaration, Element, @cil_declaration {
2525

2626
override Declaration getUnboundDeclaration() { result = this }
2727

28-
override predicate hasQualifiedName(string qualifier, string name) {
28+
deprecated override predicate hasQualifiedName(string qualifier, string name) {
2929
exists(string dqualifier, string dname |
3030
this.getDeclaringType().hasQualifiedName(dqualifier, dname) and
3131
qualifier = getQualifiedName(dqualifier, dname)
3232
) and
3333
name = this.getName()
3434
}
35+
36+
override predicate hasFullyQualifiedName(string qualifier, string name) {
37+
exists(string dqualifier, string dname |
38+
this.getDeclaringType().hasFullyQualifiedName(dqualifier, dname) and
39+
qualifier = getQualifiedName(dqualifier, dname)
40+
) and
41+
name = this.getName()
42+
}
3543
}
3644

3745
private CS::Declaration toCSharpNonTypeParameter(Declaration d) { result.matchesHandle(d) }

csharp/ql/lib/semmle/code/cil/InstructionGroups.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class Call extends Expr, DotNet::Call, @cil_call_any {
151151

152152
override Method getARuntimeTarget() { result = this.getTarget().getAnOverrider*() }
153153

154-
override string getExtra() { result = this.getTarget().getQualifiedName() }
154+
override string getExtra() { result = this.getTarget().getFullyQualifiedName() }
155155

156156
/**
157157
* Gets the return type of the call. Methods that do not return a value

csharp/ql/lib/semmle/code/cil/Instructions.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ module Opcodes {
529529
/** Gets the type that is being tested against. */
530530
Type getTestedType() { result = this.getAccess() }
531531

532-
override string getExtra() { result = this.getTestedType().getQualifiedName() }
532+
override string getExtra() { result = this.getTestedType().getFullyQualifiedName() }
533533
}
534534

535535
/** A `castclass` instruction. */
@@ -541,7 +541,7 @@ module Opcodes {
541541
/** Gets the type that is being cast to. */
542542
Type getTestedType() { result = this.getAccess() }
543543

544-
override string getExtra() { result = this.getTestedType().getQualifiedName() }
544+
override string getExtra() { result = this.getTestedType().getFullyQualifiedName() }
545545
}
546546

547547
/** An `stloc.0` instruction. */
@@ -879,7 +879,7 @@ module Opcodes {
879879
result = this.getAccess()
880880
}
881881

882-
override string getExtra() { result = this.getType().getQualifiedName() }
882+
override string getExtra() { result = this.getType().getFullyQualifiedName() }
883883
}
884884

885885
/** An `ldelem` instruction. */

csharp/ql/lib/semmle/code/cil/Type.qll

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,22 @@ class Type extends DotNet::Type, Declaration, TypeContainer, @cil_type {
5151
*/
5252
Type getUnboundType() { cil_type(this, _, _, _, result) }
5353

54-
override predicate hasQualifiedName(string qualifier, string name) {
54+
deprecated override predicate hasQualifiedName(string qualifier, string name) {
5555
name = this.getName() and
5656
exists(string pqualifier, string pname | this.getParent().hasQualifiedName(pqualifier, pname) |
5757
qualifier = getQualifiedName(pqualifier, pname)
5858
)
5959
}
6060

61+
override predicate hasFullyQualifiedName(string qualifier, string name) {
62+
name = this.getName() and
63+
exists(string pqualifier, string pname |
64+
this.getParent().hasFullyQualifiedName(pqualifier, pname)
65+
|
66+
qualifier = getQualifiedName(pqualifier, pname)
67+
)
68+
}
69+
6170
override Location getALocation() { cil_type_location(this.getUnboundDeclaration(), result) }
6271

6372
/** Holds if this type is a class. */

csharp/ql/lib/semmle/code/cil/Variable.qll

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ class Variable extends DotNet::Variable, Declaration, DataFlowNode, @cil_variabl
2929

3030
/** A stack variable. Either a local variable (`LocalVariable`) or a parameter (`Parameter`). */
3131
class StackVariable extends Variable, @cil_stack_variable {
32-
override predicate hasQualifiedName(string qualifier, string name) { none() }
32+
deprecated override predicate hasQualifiedName(string qualifier, string name) { none() }
33+
34+
override predicate hasFullyQualifiedName(string qualifier, string name) { none() }
3335
}
3436

3537
/**

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ private string getTypeParametersToString(UnboundGeneric ug) {
5656
strictconcat(Type t, int i | t = ug.getTypeParameter(i) | t.toStringWithTypes(), ", " order by i)
5757
}
5858

59-
/** Gets a string of `N` commas where `N + 1` is the number of type parameters of this unbound generic. */
60-
private string getTypeParameterCommas(UnboundGeneric ug) {
61-
result = strictconcat(int i | exists(ug.getTypeParameter(i)) | "", ",")
59+
/** Gets a string ``"`N"``, where `N` is the number of type parameters of this unbound generic. */
60+
private string getTypeParameterBacktick(UnboundGeneric ug) {
61+
result = "`" + ug.getNumberOfTypeParameters()
6262
}
6363

6464
/**
@@ -147,7 +147,7 @@ class UnboundGenericType extends ValueOrRefType, UnboundGeneric {
147147
}
148148

149149
final override string getName() {
150-
result = this.getUndecoratedName() + "<" + getTypeParameterCommas(this) + ">"
150+
result = this.getUndecoratedName() + getTypeParameterBacktick(this)
151151
}
152152
}
153153

@@ -531,7 +531,7 @@ class UnboundGenericMethod extends Method, UnboundGeneric {
531531
}
532532

533533
final override string getName() {
534-
result = this.getUndecoratedName() + "<" + getTypeParameterCommas(this) + ">"
534+
result = this.getUndecoratedName() + getTypeParameterBacktick(this)
535535
}
536536

537537
final override string getUndecoratedName() { methods(this, result, _, _, _) }

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

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,17 @@ private import Implements
99
private import TypeRef
1010
private import commons.QualifiedName
1111

12-
private module QualifiedNameInput implements QualifiedNameInputSig { }
12+
private module QualifiedNameInput implements QualifiedNameInputSig {
13+
string getUnboundGenericSuffix(UnboundGeneric ug) {
14+
result = "<" + strictconcat(int i | exists(ug.getTypeParameter(i)) | "", ",") + ">"
15+
}
16+
}
17+
18+
private module FullyQualifiedNameInput implements QualifiedNameInputSig {
19+
string getUnboundGenericSuffix(UnboundGeneric ug) {
20+
result = "`" + ug.getNumberOfTypeParameters()
21+
}
22+
}
1323

1424
/**
1525
* A declaration.
@@ -24,11 +34,17 @@ class Declaration extends DotNet::Declaration, Element, @declaration {
2434

2535
override string toString() { result = this.getName() }
2636

27-
override predicate hasQualifiedName(string qualifier, string name) {
37+
deprecated override predicate hasQualifiedName(string qualifier, string name) {
2838
QualifiedName<QualifiedNameInput>::hasQualifiedName(this, qualifier, name)
2939
}
3040

41+
override predicate hasFullyQualifiedName(string qualifier, string name) {
42+
QualifiedName<FullyQualifiedNameInput>::hasQualifiedName(this, qualifier, name)
43+
}
44+
3145
/**
46+
* DEPRECATED: Use `getFullyQualifiedNameWithTypes` instead.
47+
*
3248
* Gets the fully qualified name of this declaration, including types, for example
3349
* the fully qualified name with types of `M` on line 3 is `N.C.M(int, string)` in
3450
*
@@ -40,7 +56,7 @@ class Declaration extends DotNet::Declaration, Element, @declaration {
4056
* }
4157
* ```
4258
*/
43-
string getQualifiedNameWithTypes() {
59+
deprecated string getQualifiedNameWithTypes() {
4460
exists(string qual |
4561
qual = this.getDeclaringType().getQualifiedName() and
4662
if this instanceof NestedType
@@ -49,6 +65,27 @@ class Declaration extends DotNet::Declaration, Element, @declaration {
4965
)
5066
}
5167

68+
/**
69+
* Gets the fully qualified name of this declaration, including types, for example
70+
* the fully qualified name with types of `M` on line 3 is `N.C.M(int, string)` in
71+
*
72+
* ```csharp
73+
* namespace N {
74+
* class C {
75+
* void M(int i, string s) { }
76+
* }
77+
* }
78+
* ```
79+
*/
80+
string getFullyQualifiedNameWithTypes() {
81+
exists(string qual |
82+
qual = this.getDeclaringType().getFullyQualifiedName() and
83+
if this instanceof NestedType
84+
then result = qual + "+" + this.toStringWithTypes()
85+
else result = qual + "." + this.toStringWithTypes()
86+
)
87+
}
88+
5289
/**
5390
* Holds if this declaration has been generated by the compiler, for example
5491
* implicit constructors or accessors.
@@ -207,9 +244,13 @@ class Member extends DotNet::Member, Modifiable, @member {
207244

208245
override predicate isFile() { Modifiable.super.isFile() }
209246

210-
final override predicate hasQualifiedName(string namespace, string type, string name) {
247+
deprecated final override predicate hasQualifiedName(string namespace, string type, string name) {
211248
QualifiedName<QualifiedNameInput>::hasQualifiedName(this, namespace, type, name)
212249
}
250+
251+
final override predicate hasFullyQualifiedName(string namespace, string type, string name) {
252+
QualifiedName<FullyQualifiedNameInput>::hasQualifiedName(this, namespace, type, name)
253+
}
213254
}
214255

215256
private class TOverridable = @virtualizable or @callable_accessor;

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ class Namespace extends DotNet::Namespace, TypeContainer, Declaration, @namespac
3030
parent_namespace(result, this)
3131
}
3232

33-
override predicate hasQualifiedName(string qualifier, string name) {
33+
deprecated override predicate hasQualifiedName(string qualifier, string name) {
3434
DotNet::Namespace.super.hasQualifiedName(qualifier, name)
3535
}
3636

37+
override predicate hasFullyQualifiedName(string qualifier, string name) {
38+
DotNet::Namespace.super.hasFullyQualifiedName(qualifier, name)
39+
}
40+
3741
/**
3842
* Gets a type directly declared in this namespace, if any.
3943
* For example, the class `File` in

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,10 @@ predicate namespaceHasQualifiedName(DotNet::Namespace n, string qualifier, strin
2121
)
2222
}
2323

24-
/** Gets a string of `N` commas where `N + 1` is the number of type parameters of this unbound generic. */
25-
private string getTypeParameterCommas(UnboundGeneric ug) {
26-
result = strictconcat(int i | exists(ug.getTypeParameter(i)) | "", ",")
27-
}
28-
2924
/** Provides the input to `QualifiedName`. */
3025
signature module QualifiedNameInputSig {
3126
/** Gets the suffix to print after unbound generic `ug`. */
32-
default string getUnboundGenericSuffix(UnboundGeneric ug) {
33-
result = "<" + getTypeParameterCommas(ug) + ">"
34-
}
27+
string getUnboundGenericSuffix(UnboundGeneric ug);
3528
}
3629

3730
/** Provides predicates for computing fully qualified names. */

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().getQualifiedName()
123+
then prefix = f.getDeclaringType().getFullyQualifiedName()
124124
else prefix = "this"
125125
)
126126
}

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

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -174,23 +174,20 @@ SummaryComponent interpretComponentSpecific(AccessPathToken c) {
174174
or
175175
c = "WithElement" and result = SummaryComponent::withContent(any(ElementContent ec))
176176
or
177-
// Qualified names may contain commas,such as in `Tuple<,>`, so get the entire argument list
178-
// rather than an individual argument.
179177
exists(Field f |
180-
c.getName() = "Field" and
181-
c.getArgumentList() = f.getQualifiedName() and
178+
c.getAnArgument("Field") = f.getFullyQualifiedName() and
182179
result = SummaryComponent::content(any(FieldContent fc | fc.getField() = f))
183180
)
184181
or
185182
exists(Property p |
186-
c.getName() = "Property" and
187-
c.getArgumentList() = p.getQualifiedName() and
183+
184+
c.getAnArgument("Property") = p.getFullyQualifiedName() and
188185
result = SummaryComponent::content(any(PropertyContent pc | pc.getProperty() = p))
189186
)
190187
or
191188
exists(SyntheticField f |
192-
c.getName() = "SyntheticField" and
193-
c.getArgumentList() = f and
189+
190+
c.getAnArgument("SyntheticField") = f and
194191
result = SummaryComponent::content(any(SyntheticFieldContent sfc | sfc.getField() = f))
195192
)
196193
}
@@ -199,9 +196,9 @@ SummaryComponent interpretComponentSpecific(AccessPathToken c) {
199196
private string getContentSpecific(Content c) {
200197
c = TElementContent() and result = "Element"
201198
or
202-
exists(Field f | c = TFieldContent(f) and result = "Field[" + f.getQualifiedName() + "]")
199+
exists(Field f | c = TFieldContent(f) and result = "Field[" + f.getFullyQualifiedName() + "]")
203200
or
204-
exists(Property p | c = TPropertyContent(p) and result = "Property[" + p.getQualifiedName() + "]")
201+
exists(Property p | c = TPropertyContent(p) and result = "Property[" + p.getFullyQualifiedName() + "]")
205202
or
206203
exists(SyntheticField f | c = TSyntheticFieldContent(f) and result = "SyntheticField[" + f + "]")
207204
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ class ExternalApiUsedWithUntrustedData extends TExternalApi {
144144
|
145145
this = TExternalApiParameter(m, index) and
146146
result =
147-
m.getDeclaringType().getQualifiedName() + "." + m.toStringWithTypes() + " [" + indexString +
148-
"]"
147+
m.getDeclaringType().getFullyQualifiedName() + "." + m.toStringWithTypes() + " [" +
148+
indexString + "]"
149149
)
150150
}
151151
}

csharp/ql/lib/semmle/code/dotnet/Declaration.qll

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,26 @@ class Member extends Declaration, @dotnet_member {
7979
predicate isFile() { none() }
8080

8181
/**
82+
* DEPRECATED: Use `hasFullyQualifiedName` instead.
83+
*
8284
* Holds if this member has name `name` and is defined in type `type`
8385
* with namespace `namespace`.
8486
*/
8587
cached
86-
predicate hasQualifiedName(string namespace, string type, string name) {
88+
deprecated predicate hasQualifiedName(string namespace, string type, string name) {
8789
this.getDeclaringType().hasQualifiedName(namespace, type) and
8890
name = this.getName()
8991
}
92+
93+
/**
94+
* Holds if this member has name `name` and is defined in type `type`
95+
* with namespace `namespace`.
96+
*/
97+
cached
98+
predicate hasFullyQualifiedName(string namespace, string type, string name) {
99+
this.getDeclaringType().hasFullyQualifiedName(namespace, type) and
100+
name = this.getName()
101+
}
90102
}
91103

92104
/** A property. */

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

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,34 @@ class NamedElement extends Element, @dotnet_named_element {
9090
* ```
9191
*/
9292
cached
93-
final string getQualifiedName() {
93+
deprecated final string getQualifiedName() {
9494
exists(string qualifier, string name | this.hasQualifiedName(qualifier, name) |
9595
if qualifier = "" then result = name else result = qualifier + "." + name
9696
)
9797
}
9898

99+
/**
100+
* Gets the fully qualified name of this element, for example the
101+
* fully qualified name of `M` on line 3 is `N.C.M` in
102+
*
103+
* ```csharp
104+
* namespace N {
105+
* class C {
106+
* void M(int i, string s) { }
107+
* }
108+
* }
109+
* ```
110+
*
111+
* Unbound generic types, such as `IList<T>`, are represented as
112+
* ``System.Collections.Generic.IList`1``.
113+
*/
114+
cached
115+
final string getFullyQualifiedName() {
116+
exists(string qualifier, string name | this.hasFullyQualifiedName(qualifier, name) |
117+
if qualifier = "" then result = name else result = qualifier + "." + name
118+
)
119+
}
120+
99121
/**
100122
* DEPRECATED: Use `hasQualifiedName/2` instead.
101123
* Holds if this element has qualified name `qualifiedName`, for example
@@ -105,9 +127,19 @@ class NamedElement extends Element, @dotnet_named_element {
105127
qualifiedName = this.getQualifiedName()
106128
}
107129

108-
/** Holds if this element has the qualified name `qualifier`.`name`. */
130+
/**
131+
* DEPRECATED: Use `hasFullyQualifiedName` instead.
132+
*
133+
* Holds if this element has the qualified name `qualifier`.`name`.
134+
*/
135+
cached
136+
deprecated predicate hasQualifiedName(string qualifier, string name) {
137+
qualifier = "" and name = this.getName()
138+
}
139+
140+
/** Holds if this element has the fully qualified name `qualifier`.`name`. */
109141
cached
110-
predicate hasQualifiedName(string qualifier, string name) {
142+
predicate hasFullyQualifiedName(string qualifier, string name) {
111143
qualifier = "" and name = this.getName()
112144
}
113145

0 commit comments

Comments
 (0)