Skip to content

Commit 4054dc4

Browse files
committed
C#: Speedup Element::getLabel()
1 parent c70a0a6 commit 4054dc4

File tree

3 files changed

+76
-20
lines changed

3 files changed

+76
-20
lines changed

csharp/ql/src/semmle/code/dotnet/Callable.qll

Lines changed: 49 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,26 +27,66 @@ class Callable extends Declaration, @dotnet_callable {
2727
/** Holds if this callable can return expression `e`. */
2828
predicate canReturn(Expr e) { none() }
2929

30-
final override string getLabel() {
31-
result = getReturnTypeLabel() + " " + getDeclaringType().getLabel() + "." + getUndecoratedName()
32-
+ getGenericsLabel(this) + getMethodParams()
30+
pragma[noinline]
31+
private string getDeclaringTypeLabel() { result = this.getDeclaringType().getLabel() }
32+
33+
pragma[noinline]
34+
private string getParameterTypeLabelNonGeneric(int p) {
35+
not this instanceof Generic and
36+
result = this.getParameter(p).getType().getLabel()
3337
}
3438

35-
private string getReturnTypeLabel() {
36-
if exists(getReturnType()) then result = getReturnType().getLabel() else result = "System.Void"
39+
language[monotonicAggregates]
40+
pragma[nomagic]
41+
private string getMethodParamListNonGeneric() {
42+
result = concat(int p |
43+
p in [0 .. this.getNumberOfParameters() - 1]
44+
|
45+
this.getParameterTypeLabelNonGeneric(p), "," order by p
46+
)
3747
}
3848

39-
private string getMethodParams() { result = "(" + getMethodParamList() + ")" }
49+
pragma[noinline]
50+
private string getParameterTypeLabelGeneric(int p) {
51+
this instanceof Generic and
52+
result = this.getParameter(p).getType().getLabel()
53+
}
4054

4155
language[monotonicAggregates]
42-
private string getMethodParamList() {
56+
pragma[nomagic]
57+
private string getMethodParamListGeneric() {
4358
result = concat(int p |
44-
exists(getParameter(p))
59+
p in [0 .. this.getNumberOfParameters() - 1]
4560
|
46-
getParameter(p).getType().getLabel(), "," order by p
61+
this.getParameterTypeLabelGeneric(p), "," order by p
4762
)
4863
}
4964

65+
pragma[noinline]
66+
private string getLabelNonGeneric() {
67+
not this instanceof Generic and
68+
result = this.getReturnTypeLabel() + " " + this.getDeclaringTypeLabel() + "." +
69+
this.getUndecoratedName() + "(" + this.getMethodParamListNonGeneric() + ")"
70+
}
71+
72+
pragma[noinline]
73+
private string getLabelGeneric() {
74+
result = this.getReturnTypeLabel() + " " + this.getDeclaringTypeLabel() + "." +
75+
this.getUndecoratedName() + getGenericsLabel(this) + "(" + this.getMethodParamListGeneric() +
76+
")"
77+
}
78+
79+
final override string getLabel() {
80+
result = this.getLabelNonGeneric() or
81+
result = this.getLabelGeneric()
82+
}
83+
84+
private string getReturnTypeLabel() {
85+
result = getReturnType().getLabel()
86+
or
87+
not exists(this.getReturnType()) and result = "System.Void"
88+
}
89+
5090
override string getUndecoratedName() { result = getName() }
5191

5292
/** Gets the return type of this callable. */

csharp/ql/src/semmle/code/dotnet/Generics.qll

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,23 @@ abstract class ConstructedGeneric extends Generic {
6666
*
6767
* Constructs the label suffix for a generic method or type.
6868
*/
69-
string getGenericsLabel(Declaration d) {
70-
result = "`" + d.(UnboundGeneric).getNumberOfTypeParameters()
69+
string getGenericsLabel(Generic g) {
70+
result = "`" + g.(UnboundGeneric).getNumberOfTypeParameters()
7171
or
72-
result = "<" + typeArgs(d) + ">"
73-
or
74-
not d instanceof Generic and result = ""
72+
result = "<" + typeArgs(g) + ">"
73+
}
74+
75+
pragma[noinline]
76+
private string getTypeArgumentLabel(ConstructedGeneric generic, int p) {
77+
result = generic.getTypeArgument(p).getLabel()
7578
}
7679

7780
language[monotonicAggregates]
81+
pragma[nomagic]
7882
private string typeArgs(ConstructedGeneric generic) {
7983
result = concat(int p |
80-
exists(generic.getTypeArgument(p))
84+
p in [0 .. generic.getNumberOfTypeArguments() - 1]
8185
|
82-
generic.getTypeArgument(p).getLabel(), ","
86+
getTypeArgumentLabel(generic, p), ","
8387
)
8488
}

csharp/ql/src/semmle/code/dotnet/Type.qll

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ class ValueOrRefType extends Type, @dotnet_valueorreftype {
2323
/** Gets the namespace declaring this type, if any. */
2424
Namespace getDeclaringNamespace() { none() }
2525

26-
override string getLabel() {
27-
result = getPrefixWithTypes() + getUndecoratedName() + getGenericsLabel(this)
28-
}
29-
3026
private string getPrefixWithTypes() {
3127
result = getDeclaringType().getLabel() + "."
3228
or
@@ -35,6 +31,22 @@ class ValueOrRefType extends Type, @dotnet_valueorreftype {
3531
else result = getDeclaringNamespace().getQualifiedName() + "."
3632
}
3733

34+
pragma[noinline]
35+
private string getLabelNonGeneric() {
36+
not this instanceof Generic and
37+
result = this.getPrefixWithTypes() + this.getUndecoratedName()
38+
}
39+
40+
pragma[noinline]
41+
private string getLabelGeneric() {
42+
result = this.getPrefixWithTypes() + this.getUndecoratedName() + getGenericsLabel(this)
43+
}
44+
45+
override string getLabel() {
46+
result = this.getLabelNonGeneric() or
47+
result = this.getLabelGeneric()
48+
}
49+
3850
/** Gets a base type of this type, if any. */
3951
ValueOrRefType getABaseType() { none() }
4052
}

0 commit comments

Comments
 (0)