Skip to content

Commit f044c83

Browse files
committed
C#: Add static call graph tests
1 parent 2db588f commit f044c83

File tree

3 files changed

+220
-0
lines changed

3 files changed

+220
-0
lines changed
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Out of scope:
2+
// - overloading
3+
// - accessibility
4+
// - other callables than methods
5+
6+
namespace N1
7+
{
8+
public class C1
9+
{
10+
public void M1() { }
11+
12+
public void M2(C1 c1) // $ TypeMention=N1.C1
13+
{
14+
M1(); // $ StaticTarget=N1.C1.M1
15+
this.M1(); // $ StaticTarget=N1.C1.M1
16+
17+
c1.M1(); // $ StaticTarget=N1.C1.M1
18+
19+
C1 c2 = null; // $ TypeMention=N1.C1
20+
c2.M1(); // $ StaticTarget=N1.C1.M1
21+
22+
var c3 = new C1(); // $ TypeMention=N1.C1
23+
c3.M1(); // $ StaticTarget=N1.C1.M1
24+
25+
M3(). // $ StaticTarget=N1.C1.M3
26+
M1(); // $ StaticTarget=N1.C1.M1
27+
28+
var c4 = M3(); // $ StaticTarget=N1.C1.M3
29+
c4.M1(); // $ StaticTarget=N1.C1.M1
30+
}
31+
32+
public C1 M3() => throw null; // $ TypeMention=N1.C1
33+
} // $ Class=N1.C1
34+
}
35+
36+
namespace N2
37+
{
38+
using N1;
39+
40+
public class C1
41+
{
42+
public void M1(
43+
C1 c1 = null, // $ TypeMention=N2.C1
44+
N1.C1 c2 = null // $ TypeMention=N1.C1
45+
)
46+
{
47+
c1.M1(); // $ StaticTarget=N2.C1.M1
48+
c2.M1(); // $ StaticTarget=N1.C1.M1
49+
}
50+
} // $ Class=N2.C1
51+
52+
public class C2 : C1 // $ TypeMention=N2.C1
53+
{
54+
public void M2()
55+
{
56+
M1(); // $ StaticTarget=N2.C1.M1
57+
this.M1(); // $ StaticTarget=N2.C1.M1
58+
base.M1(); // $ StaticTarget=N2.C1.M1
59+
60+
C1 c1 = // $ TypeMention=N2.C1
61+
new C2(); // $ TypeMention=N2.C2
62+
c1.M1(); // $ StaticTarget=N2.C1.M1
63+
}
64+
} // $ Class=N2.C2
65+
66+
public class C3 : C2 // $ TypeMention=N2.C2
67+
{
68+
public new void M2()
69+
{
70+
M2(); // $ StaticTarget=N2.C3.M2
71+
C3 c3 = null; // $ TypeMention=N2.C3
72+
c3.M2(); // $ StaticTarget=N2.C3.M2
73+
C2 c2 = c3; // $ TypeMention=N2.C2
74+
c2.M2(); // $ StaticTarget=N2.C2.M2
75+
}
76+
} // $ Class=N2.C3
77+
}
78+
79+
namespace N3
80+
{
81+
using N1;
82+
83+
public class C2
84+
{
85+
C1 Field1; // $ TypeMention=N1.C1
86+
N1.C1 Field2; // $ TypeMention=N1.C1
87+
C2 Field3; // $ TypeMention=N3.C2
88+
89+
C1 Prop1 => null; // $ TypeMention=N1.C1
90+
N1.C1 Prop2 => null; // $ TypeMention=N1.C1
91+
C2 Prop3 => null; // $ TypeMention=N3.C2
92+
93+
public void M1(
94+
C1 c1, // $ TypeMention=N1.C1
95+
N1.C1 c2 // $ TypeMention=N1.C1
96+
)
97+
{
98+
c1.M1(); // $ StaticTarget=N1.C1.M1
99+
c2.M1(); // $ StaticTarget=N1.C1.M1
100+
101+
Field1.M1(); // $ StaticTarget=N1.C1.M1
102+
Field2.M1(); // $ StaticTarget=N1.C1.M1
103+
Field3.M1(null, null); // $ StaticTarget=N3.C2.M1
104+
{
105+
// shadows outer field
106+
C2 Field1 = null; // $ TypeMention=N3.C2
107+
Field1.M1(null, null); // $ StaticTarget=N3.C2.M1
108+
this.Field1.M1(); // $ StaticTarget=N1.C1.M1
109+
}
110+
111+
Prop1.M1(); // $ StaticTarget=N1.C1.M1
112+
Prop2.M1(); // $ StaticTarget=N1.C1.M1
113+
Prop3.M1(null, null); // $ StaticTarget=N3.C2.M1
114+
{
115+
// shadows outer property
116+
N2.C2 Prop1 = null; // $ TypeMention=N2.C2
117+
Prop1.M1(); // $ StaticTarget=N2.C1.M1
118+
this.Prop1.M1(); // $ StaticTarget=N1.C1.M1
119+
}
120+
}
121+
} // $ Class=N3.C2
122+
}
123+
124+
namespace N4
125+
{
126+
public class C1
127+
{
128+
public virtual void M1()
129+
{
130+
this.M1(); // $ StaticTarget=N4.C1.M1
131+
}
132+
} // $ Class=N4.C1
133+
134+
public class C2 : C1 // $ TypeMention=N4.C1
135+
{
136+
public override void M1()
137+
{
138+
this.M1(); // $ StaticTarget=N4.C2.M1
139+
base.M1(); // $ StaticTarget=N4.C1.M1
140+
}
141+
} // $ Class=N4.C2
142+
}
143+
144+
namespace N5
145+
{
146+
public class C1 : N4.C1 // $ TypeMention=N4.C1
147+
{
148+
public void M2()
149+
{
150+
this.M1(); // $ StaticTarget=N4.C1.M1
151+
}
152+
} // $ Class=N5.C1
153+
154+
public class C2 : N4.C1 // $ TypeMention=N4.C1
155+
{
156+
public override void M1()
157+
{
158+
this.M1(); // $ StaticTarget=N5.C2.M1
159+
base.M1(); // $ StaticTarget=N4.C1.M1
160+
}
161+
} // $ Class=N5.C2
162+
}
163+
164+
namespace N6
165+
{
166+
using alias = N5;
167+
168+
public class C1
169+
{
170+
public void M1(
171+
alias::C2 c2 // $ TypeMention=N5.C2
172+
)
173+
{
174+
c2.M1(); // $ StaticTarget=N5.C2.M1
175+
}
176+
177+
public static void M2() { }
178+
} // $ Class=N6.C1
179+
}
180+
181+
namespace N7
182+
{
183+
public class C1
184+
{
185+
public void M1()
186+
{
187+
N6.C1.M2(); // $ StaticTarget=N6.C1.M2
188+
}
189+
} // $ Class=N7.C1
190+
}
191+
192+
namespace N8
193+
{
194+
using static N6.C1; // $ TypeMention=N6.C1
195+
196+
public class C1
197+
{
198+
public void M1()
199+
{
200+
M2(); // $ StaticTarget=N6.C1.M2
201+
}
202+
} // $ Class=N8.C1
203+
}

csharp/ql/test/library-tests/call-graph/CallGraph.expected

Whitespace-only changes.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import csharp
2+
import TestUtilities.InlineExpectationsTest
3+
4+
class CallGraphTest extends InlineExpectationsTest {
5+
CallGraphTest() { this = "CallGraphTest" }
6+
7+
override string getARelevantTag() { result = "StaticTarget" }
8+
9+
override predicate hasActualResult(Location location, string element, string tag, string value) {
10+
exists(MethodCall mc |
11+
element = mc.toString() and
12+
tag = "StaticTarget" and
13+
value = mc.getTarget().getQualifiedName() and
14+
mc.getLocation() = location
15+
)
16+
}
17+
}

0 commit comments

Comments
 (0)