Skip to content

Commit 8375c49

Browse files
authored
Merge pull request github#18166 from tamasvajk/fix/db-quality-query-2
C#: Fix calls with no target in DB quality query
2 parents f56e337 + b8fd20e commit 8375c49

File tree

4 files changed

+60
-6
lines changed

4 files changed

+60
-6
lines changed

csharp/ql/src/Telemetry/DatabaseQuality.qll

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,24 +68,36 @@ module CallTargetStats implements StatsSig {
6868
)
6969
}
7070

71-
private predicate isInitializedWithCollectionInitializer(PropertyCall c) {
71+
private predicate isInitializedWithObjectOrCollectionInitializer(PropertyCall c) {
7272
exists(Property p, AssignExpr assign |
7373
p = c.getProperty() and
7474
assign = c.getParent() and
7575
assign.getLValue() = c and
76-
assign.getRValue() instanceof CollectionInitializer
76+
assign.getRValue() instanceof ObjectOrCollectionInitializer
7777
)
7878
}
7979

80+
private predicate isEventFieldAccess(EventCall c) {
81+
exists(Event e | c.getEvent() = e |
82+
forall(Accessor a | e.getAnAccessor() = a | a.isCompilerGenerated())
83+
)
84+
}
85+
86+
private predicate isTypeParameterInstantiation(ObjectCreation e) {
87+
e.getType() instanceof TypeParameter
88+
}
89+
8090
additional predicate isNotOkCall(Call c) {
8191
not exists(c.getTarget()) and
8292
not c instanceof DelegateCall and
8393
not c instanceof DynamicExpr and
8494
not isNoSetterPropertyCallInConstructor(c) and
8595
not isNoSetterPropertyInitialization(c) and
8696
not isAnonymousObjectMemberDeclaration(c) and
87-
not isInitializedWithCollectionInitializer(c) and
88-
not c.getParent+() instanceof NameOfExpr
97+
not isInitializedWithObjectOrCollectionInitializer(c) and
98+
not c.getParent+() instanceof NameOfExpr and
99+
not isEventFieldAccess(c) and
100+
not isTypeParameterInstantiation(c)
89101
}
90102

91103
int getNumberOfNotOk() { result = count(Call c | isNotOkCall(c)) }
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
2+
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
3+
| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer |
4+
| Quality.cs:34:21:34:25 | object creation of type null | Call without target $@. | Quality.cs:34:21:34:25 | object creation of type null | object creation of type null |

csharp/ql/test/query-tests/Telemetry/DatabaseQuality/NoTarget.expected

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,12 @@
44
| Quality.cs:15:24:15:34 | access to property MyProperty3 | Call without target $@. | Quality.cs:15:24:15:34 | access to property MyProperty3 | access to property MyProperty3 |
55
| Quality.cs:15:24:15:46 | access to property MyProperty2 | Call without target $@. | Quality.cs:15:24:15:46 | access to property MyProperty2 | access to property MyProperty2 |
66
| Quality.cs:19:13:19:23 | access to property MyProperty4 | Call without target $@. | Quality.cs:19:13:19:23 | access to property MyProperty4 | access to property MyProperty4 |
7-
| Quality.cs:24:16:24:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:24:16:24:26 | access to property MyProperty2 | access to property MyProperty2 |
7+
| Quality.cs:20:13:20:23 | access to property MyProperty6 | Call without target $@. | Quality.cs:20:13:20:23 | access to property MyProperty6 | access to property MyProperty6 |
8+
| Quality.cs:23:9:23:14 | access to event Event1 | Call without target $@. | Quality.cs:23:9:23:14 | access to event Event1 | access to event Event1 |
9+
| Quality.cs:23:9:23:30 | delegate call | Call without target $@. | Quality.cs:23:9:23:30 | delegate call | delegate call |
10+
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
11+
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
12+
| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer |
13+
| Quality.cs:34:21:34:25 | object creation of type null | Call without target $@. | Quality.cs:34:21:34:25 | object creation of type null | object creation of type null |
14+
| Quality.cs:38:16:38:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:38:16:38:26 | access to property MyProperty2 | access to property MyProperty2 |
15+
| Quality.cs:50:20:50:26 | object creation of type T | Call without target $@. | Quality.cs:50:20:50:26 | object creation of type T | object creation of type T |

csharp/ql/test/query-tests/Telemetry/DatabaseQuality/Quality.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,43 @@ public Test()
1616

1717
new Test()
1818
{
19-
MyProperty4 = { 1, 2, 3 }
19+
MyProperty4 = { 1, 2, 3 },
20+
MyProperty6 = { [1] = "" }
2021
};
22+
23+
Event1.Invoke(this, 5);
24+
25+
var str = "abcd";
26+
var sub = str[..3]; // TODO: this is not an indexer call, but rather a `str.Substring(0, 3)` call.
27+
28+
Span<int> sp = null;
29+
var slice = sp[..3]; // TODO: this is not an indexer call, but rather a `sp.Slice(0, 3)` call.
30+
31+
Span<byte> guidBytes = stackalloc byte[16];
32+
guidBytes[08] = 1; // TODO: this indexer call has no target, because the target is a `ref` returning getter.
33+
34+
new MyList([new(), new Test()]); // TODO: the `new()` call has no target, which is unexpected, as we know at compile time, that this is a `new Test()` call.
2135
}
2236

2337
public int MyProperty1 { get; }
2438
public int MyProperty2 { get; } = 42;
2539
public Test MyProperty3 { get; set; }
2640
public List<int> MyProperty4 { get; }
2741
static int MyProperty5 { get; }
42+
public Dictionary<int, string> MyProperty6 { get; }
43+
44+
public event EventHandler<int> Event1;
45+
46+
class Gen<T> where T : new()
47+
{
48+
public static T Factory()
49+
{
50+
return new T();
51+
}
52+
}
53+
54+
class MyList
55+
{
56+
public MyList(IEnumerable<Test> init) { }
57+
}
2858
}

0 commit comments

Comments
 (0)