Skip to content

Commit c040daa

Browse files
committed
C#: Add extensions test.
1 parent 849823e commit c040daa

File tree

7 files changed

+412
-0
lines changed

7 files changed

+412
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
4+
public static class MyExtensionTypes
5+
{
6+
extension([NotNull] string s)
7+
{
8+
public void M11() { }
9+
}
10+
extension(ref readonly int i1)
11+
{
12+
public void M21() { }
13+
}
14+
extension(in int i2)
15+
{
16+
public void M31() { }
17+
}
18+
extension(ref int i3)
19+
{
20+
public void M41() { }
21+
}
22+
extension(string? s)
23+
{
24+
public void M51() { }
25+
}
26+
extension<T1>([NotNullWhen(true)] T1 t1) where T1 : class
27+
{
28+
public void M61<T2>(object o, T2 t2) { }
29+
}
30+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
extensionTypeReceiverParameter
2+
| extensionTypes.cs:6:5:9:5 | extension(String) | extensionTypes.cs:6:32:6:32 | s |
3+
| extensionTypes.cs:10:5:13:5 | extension(Int32) | extensionTypes.cs:10:32:10:33 | i1 |
4+
| extensionTypes.cs:14:5:17:5 | extension(Int32) | extensionTypes.cs:14:22:14:23 | i2 |
5+
| extensionTypes.cs:18:5:21:5 | extension(Int32) | extensionTypes.cs:18:23:18:24 | i3 |
6+
| extensionTypes.cs:22:5:25:5 | extension(String) | extensionTypes.cs:22:23:22:23 | s |
7+
| extensionTypes.cs:26:5:29:5 | extension(T1)`1 | extensionTypes.cs:26:42:26:43 | t1 |
8+
| extensions.cs:6:5:17:5 | extension(String) | extensions.cs:6:22:6:22 | s |
9+
| extensions.cs:26:5:35:5 | extension(Object)<Object> | extensions.cs:26:20:26:20 | t |
10+
| extensions.cs:26:5:35:5 | extension(String)<String> | extensions.cs:26:20:26:20 | t |
11+
| extensions.cs:26:5:35:5 | extension(T)`1 | extensions.cs:26:20:26:20 | t |
12+
extensionTypeExtendedType
13+
| extensionTypes.cs:6:5:9:5 | extension(String) | string |
14+
| extensionTypes.cs:10:5:13:5 | extension(Int32) | int |
15+
| extensionTypes.cs:14:5:17:5 | extension(Int32) | int |
16+
| extensionTypes.cs:18:5:21:5 | extension(Int32) | int |
17+
| extensionTypes.cs:22:5:25:5 | extension(String) | string |
18+
| extensionTypes.cs:26:5:29:5 | extension(T1)`1 | T1 |
19+
| extensions.cs:6:5:17:5 | extension(String) | string |
20+
| extensions.cs:19:5:24:5 | extension(Object) | object |
21+
| extensions.cs:26:5:35:5 | extension(Object)<Object> | object |
22+
| extensions.cs:26:5:35:5 | extension(String)<String> | string |
23+
| extensions.cs:26:5:35:5 | extension(T)`1 | T |
24+
extensionTypeReceiverParameterAttribute
25+
| extensionTypes.cs:6:5:9:5 | extension(String) | extensionTypes.cs:6:32:6:32 | s | extensionTypes.cs:6:16:6:22 | [NotNull(...)] |
26+
| extensionTypes.cs:26:5:29:5 | extension(T1)`1 | extensionTypes.cs:26:42:26:43 | t1 | extensionTypes.cs:26:20:26:30 | [NotNullWhen(...)] |
27+
extensionTypeReceiverParameterModifier
28+
| extensionTypes.cs:10:5:13:5 | extension(Int32) | extensionTypes.cs:10:32:10:33 | i1 | ref readonly |
29+
| extensionTypes.cs:14:5:17:5 | extension(Int32) | extensionTypes.cs:14:22:14:23 | i2 | in |
30+
| extensionTypes.cs:18:5:21:5 | extension(Int32) | extensionTypes.cs:18:23:18:24 | i3 | ref |
31+
extensionTypeParameterConstraints
32+
| extensionTypes.cs:26:5:29:5 | extension(T1)`1 | extensionTypes.cs:26:15:26:16 | T1 | file://:0:0:0:0 | where T1: ... |
33+
| extensions.cs:26:5:35:5 | extension(T)`1 | extensions.cs:26:15:26:15 | T | file://:0:0:0:0 | where T: ... |
34+
syntheticParameterModifier
35+
| extensionTypes.cs:10:5:13:5 | extension(Int32) | extensionTypes.cs:12:21:12:23 | M21 | extensionTypes.cs:10:32:10:33 | i1 | ref readonly |
36+
| extensionTypes.cs:14:5:17:5 | extension(Int32) | extensionTypes.cs:16:21:16:23 | M31 | extensionTypes.cs:14:22:14:23 | i2 | in |
37+
| extensionTypes.cs:18:5:21:5 | extension(Int32) | extensionTypes.cs:20:21:20:23 | M41 | extensionTypes.cs:18:23:18:24 | i3 | ref |
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import csharp
2+
3+
private predicate inTestFile(ExtensionType et) {
4+
et.getFile().getBaseName() = ["extensions.cs", "extensionTypes.cs"]
5+
}
6+
7+
private string getModifier(Parameter p) {
8+
p.isIn() and result = "in"
9+
or
10+
p.isRef() and result = "ref"
11+
or
12+
p.isReadonlyRef() and result = "ref readonly"
13+
}
14+
15+
query predicate extensionTypeReceiverParameter(ExtensionType et, Parameter p) {
16+
inTestFile(et) and
17+
p = et.getReceiverParameter()
18+
}
19+
20+
query predicate extensionTypeExtendedType(ExtensionType et, string t) {
21+
inTestFile(et) and
22+
t = et.getExtendedType().toStringWithTypes()
23+
}
24+
25+
query predicate extensionTypeReceiverParameterAttribute(ExtensionType et, Parameter p, Attribute a) {
26+
inTestFile(et) and
27+
et.getReceiverParameter() = p and
28+
p.getAnAttribute() = a
29+
}
30+
31+
query predicate extensionTypeReceiverParameterModifier(
32+
ExtensionType et, Parameter p, string modifier
33+
) {
34+
inTestFile(et) and
35+
et.getReceiverParameter() = p and
36+
modifier = getModifier(p)
37+
}
38+
39+
query predicate extensionTypeParameterConstraints(
40+
UnboundGeneric ug, TypeParameter tp, TypeParameterConstraints c
41+
) {
42+
inTestFile(ug) and
43+
ug instanceof ExtensionType and
44+
tp = ug.getATypeParameter() and
45+
tp.getConstraints() = c
46+
}
47+
48+
query predicate syntheticParameterModifier(
49+
ExtensionType et, ExtensionMethod em, Parameter p, string modifier
50+
) {
51+
inTestFile(et) and
52+
em.getDeclaringType() = et and
53+
p = em.getParameter(0) and
54+
not em.isStatic() and
55+
modifier = getModifier(p)
56+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
public static class MyExtensions
5+
{
6+
extension(string s)
7+
{
8+
public bool Prop1 => s.Length > 0;
9+
public bool Prop2 { get { return true; } set { } }
10+
public static bool StaticProp1 { get { return false; } }
11+
public bool M1() => s is not null;
12+
public string M2(string other) { return s + other; }
13+
public static int StaticM1() { return 0; }
14+
public static int StaticM2(string x) { return x.Length; }
15+
public static string operator *(int a, string b) { return ""; }
16+
public T StringGenericM1<T>(T t, object o) { return t; }
17+
}
18+
19+
extension(object)
20+
{
21+
public static int StaticObjectM1() { return 0; }
22+
public static int StaticObjectM2(string s) { return s.Length; }
23+
public static bool StaticProp => true;
24+
}
25+
26+
extension<T>(T t) where T : class
27+
{
28+
public bool GenericProp1 => t is not null;
29+
public bool GenericProp2 { get { return true; } set { } }
30+
public bool GenericM1() => t is not null;
31+
public void GenericM2<S>(S other) { }
32+
public void GenericStaticM1() { }
33+
public static void GenericStaticM2<S>(S other) { }
34+
public static T operator +(T a, T b) { return null; }
35+
}
36+
}
37+
38+
public static class ClassicExtensions
39+
{
40+
public static bool M3(this string s) => s is not null;
41+
}
42+
43+
public class C
44+
{
45+
public static void CallingExtensions()
46+
{
47+
var s = "Hello World.";
48+
49+
// Calling the extensions properties
50+
var x11 = s.Prop1;
51+
var x12 = s.Prop2;
52+
s.Prop2 = true;
53+
var x13 = string.StaticProp1;
54+
var x14 = object.StaticProp;
55+
56+
// Calling the extensions methods.
57+
var x21 = s.M1();
58+
var x22 = s.M2("!!!");
59+
var x23 = string.StaticM1();
60+
var x24 = string.StaticM2(s);
61+
var x25 = object.StaticObjectM1();
62+
var x26 = object.StaticObjectM2(s);
63+
64+
// Calling the extension operator.
65+
var x30 = 3 * s;
66+
67+
// Calling the classic extension method.
68+
var y = s.M3();
69+
70+
// Calling the compiler generated static extension methods.
71+
MyExtensions.M1(s);
72+
MyExtensions.M2(s, "!!!");
73+
MyExtensions.StaticM1();
74+
MyExtensions.StaticM2(s);
75+
MyExtensions.StaticObjectM1();
76+
MyExtensions.StaticObjectM2(s);
77+
78+
// Calling the compiler generated operator method.
79+
MyExtensions.op_Multiply(3, s);
80+
81+
// Calling the compiler generated methods used by the extension property accessors.
82+
MyExtensions.get_Prop1(s);
83+
MyExtensions.get_Prop2(s);
84+
MyExtensions.set_Prop2(s, false);
85+
MyExtensions.get_StaticProp();
86+
}
87+
88+
public static void CallingGenericExtensions()
89+
{
90+
var s = "Hello Generic World.";
91+
var o = new object();
92+
93+
// Calling generic extension method
94+
o.GenericM1();
95+
s.GenericM1();
96+
97+
// Calling the compiler generated static extension methods.
98+
MyExtensions.GenericM1(o);
99+
MyExtensions.GenericM1(s);
100+
101+
o.GenericM2(42);
102+
MyExtensions.GenericM2(o, 42);
103+
104+
s.StringGenericM1<int>(7, new object());
105+
MyExtensions.StringGenericM1<string>(s, "test", new object());
106+
}
107+
}

0 commit comments

Comments
 (0)