Skip to content

Commit 245b47a

Browse files
authored
Merge pull request #1017 from hvitved/csharp/get-label-performance
Approved by calumgrant
2 parents 08e7499 + 4054dc4 commit 245b47a

File tree

10 files changed

+251
-47
lines changed

10 files changed

+251
-47
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
}
Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,54 @@
1-
| Members.cs:4:11:4:15 | Class | internal |
2-
| Members.cs:7:15:7:25 | NestedClass | private |
3-
| Members.cs:10:14:10:19 | Method | private |
4-
| Members.cs:13:20:13:25 | Class2 | internal |
5-
| Members.cs:15:23:15:34 | NestedClass2 | private |
6-
| Members.cs:17:22:17:28 | Method2 | private |
7-
| Members.cs:21:15:21:23 | Interface | internal |
8-
| Members.cs:23:24:23:33 | Interface2 | internal |
9-
| Members.cs:26:10:26:13 | Enum | internal |
10-
| Members.cs:28:10:28:14 | Enum2 | internal |
11-
| Members.cs:31:12:31:17 | Struct | internal |
12-
| Members.cs:33:12:33:18 | Struct2 | internal |
1+
| Members.cs:6:11:6:15 | Class | internal |
2+
| Members.cs:9:15:9:25 | NestedClass | private |
3+
| Members.cs:12:20:12:28 | Method | private |
4+
| Members.cs:14:20:14:23 | Item | private |
5+
| Members.cs:14:34:14:36 | get_Item | private |
6+
| Members.cs:14:55:14:57 | set_Item | private |
7+
| Members.cs:16:20:16:24 | Field | private |
8+
| Members.cs:18:20:18:23 | Prop | private |
9+
| Members.cs:18:27:18:29 | get_Prop | private |
10+
| Members.cs:18:32:18:34 | set_Prop | private |
11+
| Members.cs:20:32:20:36 | Event | private |
12+
| Members.cs:20:32:20:36 | add_Event | private |
13+
| Members.cs:20:32:20:36 | remove_Event | private |
14+
| Members.cs:24:14:24:19 | Method | private |
15+
| Members.cs:26:16:26:19 | Item | private |
16+
| Members.cs:26:30:26:32 | get_Item | private |
17+
| Members.cs:26:51:26:53 | set_Item | private |
18+
| Members.cs:28:16:28:20 | Field | private |
19+
| Members.cs:30:16:30:19 | Prop | private |
20+
| Members.cs:30:23:30:25 | get_Prop | private |
21+
| Members.cs:30:28:30:30 | set_Prop | private |
22+
| Members.cs:32:28:32:32 | Event | private |
23+
| Members.cs:32:28:32:32 | add_Event | private |
24+
| Members.cs:32:28:32:32 | remove_Event | private |
25+
| Members.cs:35:20:35:25 | Class2 | internal |
26+
| Members.cs:37:23:37:34 | NestedClass2 | private |
27+
| Members.cs:39:28:39:36 | Method | private |
28+
| Members.cs:40:28:40:31 | Item | private |
29+
| Members.cs:40:42:40:44 | get_Item | private |
30+
| Members.cs:40:63:40:65 | set_Item | private |
31+
| Members.cs:41:28:41:32 | Field | private |
32+
| Members.cs:42:28:42:31 | Prop | private |
33+
| Members.cs:42:35:42:37 | get_Prop | private |
34+
| Members.cs:42:40:42:42 | set_Prop | private |
35+
| Members.cs:43:40:43:44 | Event | private |
36+
| Members.cs:43:40:43:44 | add_Event | private |
37+
| Members.cs:43:40:43:44 | remove_Event | private |
38+
| Members.cs:46:22:46:27 | Method | private |
39+
| Members.cs:47:24:47:27 | Item | private |
40+
| Members.cs:47:38:47:40 | get_Item | private |
41+
| Members.cs:47:59:47:61 | set_Item | private |
42+
| Members.cs:48:24:48:28 | Field | private |
43+
| Members.cs:49:24:49:27 | Prop | private |
44+
| Members.cs:49:31:49:33 | get_Prop | private |
45+
| Members.cs:49:36:49:38 | set_Prop | private |
46+
| Members.cs:50:36:50:40 | Event | private |
47+
| Members.cs:50:36:50:40 | add_Event | private |
48+
| Members.cs:50:36:50:40 | remove_Event | private |
49+
| Members.cs:54:15:54:23 | Interface | internal |
50+
| Members.cs:62:24:62:33 | Interface2 | internal |
51+
| Members.cs:71:10:71:13 | Enum | internal |
52+
| Members.cs:73:10:73:14 | Enum2 | internal |
53+
| Members.cs:76:12:76:17 | Struct | internal |
54+
| Members.cs:78:12:78:18 | Struct2 | internal |
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
| Members.cs:3:26:3:37 | EventHandler | Types.EventHandler |
2+
| Members.cs:6:11:6:15 | Class | Types.Class |
3+
| Members.cs:9:15:9:25 | NestedClass | Types.Class.NestedClass |
4+
| Members.cs:12:20:12:28 | Method | System.String Types.Class.NestedClass.Method`1(!0) |
5+
| Members.cs:12:27:12:27 | T | !0 |
6+
| Members.cs:14:34:14:36 | get_Item | System.String Types.Class.NestedClass.get_Item(System.Int32) |
7+
| Members.cs:14:55:14:57 | set_Item | System.Void Types.Class.NestedClass.set_Item(System.Int32,System.String) |
8+
| Members.cs:18:27:18:29 | get_Prop | System.String Types.Class.NestedClass.get_Prop() |
9+
| Members.cs:18:32:18:34 | set_Prop | System.Void Types.Class.NestedClass.set_Prop(System.String) |
10+
| Members.cs:20:32:20:36 | add_Event | System.Void Types.Class.NestedClass.add_Event(Types.EventHandler) |
11+
| Members.cs:20:32:20:36 | remove_Event | System.Void Types.Class.NestedClass.remove_Event(Types.EventHandler) |
12+
| Members.cs:24:14:24:19 | Method | System.Void Types.Class.Method() |
13+
| Members.cs:26:30:26:32 | get_Item | System.String Types.Class.get_Item(System.Int32) |
14+
| Members.cs:26:51:26:53 | set_Item | System.Void Types.Class.set_Item(System.Int32,System.String) |
15+
| Members.cs:30:23:30:25 | get_Prop | System.String Types.Class.get_Prop() |
16+
| Members.cs:30:28:30:30 | set_Prop | System.Void Types.Class.set_Prop(System.String) |
17+
| Members.cs:32:28:32:32 | add_Event | System.Void Types.Class.add_Event(Types.EventHandler) |
18+
| Members.cs:32:28:32:32 | remove_Event | System.Void Types.Class.remove_Event(Types.EventHandler) |
19+
| Members.cs:35:20:35:25 | Class2 | Types.Class2 |
20+
| Members.cs:37:23:37:34 | NestedClass2 | Types.Class2.NestedClass2 |
21+
| Members.cs:39:28:39:36 | Method | System.String Types.Class2.NestedClass2.Method`1(!0) |
22+
| Members.cs:39:35:39:35 | T | !0 |
23+
| Members.cs:40:42:40:44 | get_Item | System.String Types.Class2.NestedClass2.get_Item(System.Int32) |
24+
| Members.cs:40:63:40:65 | set_Item | System.Void Types.Class2.NestedClass2.set_Item(System.Int32,System.String) |
25+
| Members.cs:42:35:42:37 | get_Prop | System.String Types.Class2.NestedClass2.get_Prop() |
26+
| Members.cs:42:40:42:42 | set_Prop | System.Void Types.Class2.NestedClass2.set_Prop(System.String) |
27+
| Members.cs:43:40:43:44 | add_Event | System.Void Types.Class2.NestedClass2.add_Event(Types.EventHandler) |
28+
| Members.cs:43:40:43:44 | remove_Event | System.Void Types.Class2.NestedClass2.remove_Event(Types.EventHandler) |
29+
| Members.cs:46:22:46:27 | Method | System.Void Types.Class2.Method() |
30+
| Members.cs:47:38:47:40 | get_Item | System.String Types.Class2.get_Item(System.Int32) |
31+
| Members.cs:47:59:47:61 | set_Item | System.Void Types.Class2.set_Item(System.Int32,System.String) |
32+
| Members.cs:49:31:49:33 | get_Prop | System.String Types.Class2.get_Prop() |
33+
| Members.cs:49:36:49:38 | set_Prop | System.Void Types.Class2.set_Prop(System.String) |
34+
| Members.cs:50:36:50:40 | add_Event | System.Void Types.Class2.add_Event(Types.EventHandler) |
35+
| Members.cs:50:36:50:40 | remove_Event | System.Void Types.Class2.remove_Event(Types.EventHandler) |
36+
| Members.cs:54:15:54:23 | Interface | Types.Interface |
37+
| Members.cs:56:14:56:19 | Method | System.Void Types.Interface.Method() |
38+
| Members.cs:57:30:57:32 | get_Item | System.String Types.Interface.get_Item(System.Int32) |
39+
| Members.cs:57:35:57:37 | set_Item | System.Void Types.Interface.set_Item(System.Int32,System.String) |
40+
| Members.cs:58:23:58:25 | get_Prop | System.String Types.Interface.get_Prop() |
41+
| Members.cs:58:28:58:30 | set_Prop | System.Void Types.Interface.set_Prop(System.String) |
42+
| Members.cs:59:28:59:32 | add_Event | System.Void Types.Interface.add_Event(Types.EventHandler) |
43+
| Members.cs:59:28:59:32 | remove_Event | System.Void Types.Interface.remove_Event(Types.EventHandler) |
44+
| Members.cs:62:24:62:33 | Interface2 | Types.Interface2 |
45+
| Members.cs:64:14:64:19 | Method | System.Void Types.Interface2.Method() |
46+
| Members.cs:65:30:65:32 | get_Item | System.String Types.Interface2.get_Item(System.Int32) |
47+
| Members.cs:65:35:65:37 | set_Item | System.Void Types.Interface2.set_Item(System.Int32,System.String) |
48+
| Members.cs:66:23:66:25 | get_Prop | System.String Types.Interface2.get_Prop() |
49+
| Members.cs:66:28:66:30 | set_Prop | System.Void Types.Interface2.set_Prop(System.String) |
50+
| Members.cs:67:28:67:32 | add_Event | System.Void Types.Interface2.add_Event(Types.EventHandler) |
51+
| Members.cs:67:28:67:32 | remove_Event | System.Void Types.Interface2.remove_Event(Types.EventHandler) |
52+
| Members.cs:71:10:71:13 | Enum | Types.Enum |
53+
| Members.cs:73:10:73:14 | Enum2 | Types.Enum2 |
54+
| Members.cs:76:12:76:17 | Struct | Types.Struct |
55+
| Members.cs:78:12:78:18 | Struct2 | Types.Struct2 |
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import dotnet::DotNet
2+
3+
from NamedElement ne
4+
where ne.fromSource()
5+
select ne, ne.getLabel()

csharp/ql/test/library-tests/members/Members.cs

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,71 @@
11
namespace Types
22
{
3+
public delegate void EventHandler(object sender, object e);
4+
35
/*internal*/
46
class Class
57
{
68
/*private*/
7-
class NestedClass { }
9+
class NestedClass
10+
{
11+
/*private*/
12+
string Method<T>(T t) => t.ToString();
13+
/*private*/
14+
string this[int i] { get => i.ToString(); set { } }
15+
/*private*/
16+
string Field;
17+
/*private*/
18+
string Prop { get; set; }
19+
/*private*/
20+
event EventHandler Event;
21+
}
822

923
/*private*/
1024
void Method() { }
25+
/*private*/
26+
string this[int i] { get => i.ToString(); set { } }
27+
/*private*/
28+
string Field;
29+
/*private*/
30+
string Prop { get; set; }
31+
/*private*/
32+
event EventHandler Event;
1133
}
1234

1335
internal class Class2
1436
{
15-
private class NestedClass2 { }
37+
private class NestedClass2
38+
{
39+
private string Method<T>(T t) => t.ToString();
40+
private string this[int i] { get => i.ToString(); set { } }
41+
private string Field;
42+
private string Prop { get; set; }
43+
private event EventHandler Event;
44+
}
1645

17-
private void Method2() { }
46+
private void Method() { }
47+
private string this[int i] { get => i.ToString(); set { } }
48+
private string Field;
49+
private string Prop { get; set; }
50+
private event EventHandler Event;
1851
}
1952

2053
/*internal*/
21-
interface Interface { }
54+
interface Interface
55+
{
56+
void Method();
57+
string this[int i] { get; set; }
58+
string Prop { get; set; }
59+
event EventHandler Event;
60+
}
2261

23-
internal interface Interface2 { }
62+
internal interface Interface2
63+
{
64+
void Method();
65+
string this[int i] { get; set; }
66+
string Prop { get; set; }
67+
event EventHandler Event;
68+
}
2469

2570
/*internal*/
2671
enum Enum { }

csharp/ql/test/queries.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<queries language="csharp"/>
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
| /File1.cs<\|>System.Net.Http<\|>4.2.0.0 | 11 |
2-
| /File1.cs<\|>System.Private.DataContractSerialization<\|>4.1.3.0 | 2 |
3-
| /File1.cs<\|>System.Private.Xml<\|>4.0.0.0 | 2 |
4-
| /File1.cs<\|>System.Data.Common<\|>4.2.0.0 | 1 |
5-
| /File2.cs<\|>System.Net.Http<\|>4.2.0.0 | 1 |
1+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs<\|>System.Net.Http<\|>4.2.0.0 | 11 |
2+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs<\|>System.Private.DataContractSerialization<\|>4.1.3.0 | 2 |
3+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs<\|>System.Private.Xml<\|>4.0.0.0 | 2 |
4+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs<\|>System.Data.Common<\|>4.2.0.0 | 1 |
5+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File2.cs<\|>System.Net.Http<\|>4.2.0.0 | 1 |
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
| /File1.cs<\|>System.Data.Common<\|>4.2.0.0 | File1.cs:0:0:0:0 | File1.cs |
2-
| /File1.cs<\|>System.Net.Http<\|>4.2.0.0 | File1.cs:0:0:0:0 | File1.cs |
3-
| /File1.cs<\|>System.Private.DataContractSerialization<\|>4.1.3.0 | File1.cs:0:0:0:0 | File1.cs |
4-
| /File1.cs<\|>System.Private.Xml<\|>4.0.0.0 | File1.cs:0:0:0:0 | File1.cs |
5-
| /File2.cs<\|>System.Net.Http<\|>4.2.0.0 | File2.cs:0:0:0:0 | File2.cs |
1+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs<\|>System.Data.Common<\|>4.2.0.0 | File1.cs:0:0:0:0 | File1.cs |
2+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs<\|>System.Net.Http<\|>4.2.0.0 | File1.cs:0:0:0:0 | File1.cs |
3+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs<\|>System.Private.DataContractSerialization<\|>4.1.3.0 | File1.cs:0:0:0:0 | File1.cs |
4+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File1.cs<\|>System.Private.Xml<\|>4.0.0.0 | File1.cs:0:0:0:0 | File1.cs |
5+
| /query-tests/Metrics/Dependencies/ExternalDependencies/File2.cs<\|>System.Net.Http<\|>4.2.0.0 | File2.cs:0:0:0:0 | File2.cs |

0 commit comments

Comments
 (0)