-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathDatabaseQuality.qll
104 lines (84 loc) · 3.28 KB
/
DatabaseQuality.qll
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/**
* Provides database quality statistics that are reported by csharp/telemetry/extractor-information
* and perhaps warned about by csharp/diagnostics/database-quality.
*/
import csharp
import codeql.util.ReportStats
module CallTargetStats implements StatsSig {
int getNumberOfOk() { result = count(Call c | exists(c.getTarget())) }
private predicate isNoSetterPropertyCallInConstructor(PropertyCall c) {
exists(Property p, Constructor ctor |
p = c.getProperty() and
not exists(Setter a | a = p.getAnAccessor()) and
c.getEnclosingCallable() = ctor and
(
c.hasThisQualifier()
or
ctor instanceof StaticConstructor and p.getDeclaringType() = ctor.getDeclaringType()
)
)
}
private predicate isNoSetterPropertyInitialization(PropertyCall c) {
exists(Property p, AssignExpr assign |
p = c.getProperty() and
not exists(Setter a | a = p.getAnAccessor()) and
assign = c.getParent() and
assign.getLValue() = c and
assign.getParent() instanceof Property
)
}
private predicate isAnonymousObjectMemberDeclaration(PropertyCall c) {
exists(Property p, AssignExpr assign |
p = c.getProperty() and
assign = c.getParent() and
assign.getLValue() = c and
assign.getParent() instanceof ObjectInitializer and
assign.getParent().getParent() instanceof AnonymousObjectCreation
)
}
private predicate isInitializedWithObjectOrCollectionInitializer(PropertyCall c) {
exists(Property p, AssignExpr assign |
p = c.getProperty() and
assign = c.getParent() and
assign.getLValue() = c and
assign.getRValue() instanceof ObjectOrCollectionInitializer
)
}
private predicate isEventFieldAccess(EventCall c) {
exists(Event e | c.getEvent() = e |
forall(Accessor a | e.getAnAccessor() = a | a.isCompilerGenerated())
)
}
private predicate isTypeParameterInstantiation(ObjectCreation e) {
e.getType() instanceof TypeParameter
}
additional predicate isNotOkCall(Call c) {
not exists(c.getTarget()) and
not c instanceof DelegateCall and
not c instanceof DynamicExpr and
not isNoSetterPropertyCallInConstructor(c) and
not isNoSetterPropertyInitialization(c) and
not isAnonymousObjectMemberDeclaration(c) and
not isInitializedWithObjectOrCollectionInitializer(c) and
not c.getParent+() instanceof NameOfExpr and
not isEventFieldAccess(c) and
not isTypeParameterInstantiation(c)
}
int getNumberOfNotOk() { result = count(Call c | isNotOkCall(c)) }
string getOkText() { result = "calls with call target" }
string getNotOkText() { result = "calls with missing call target" }
}
private class SourceExpr extends Expr {
SourceExpr() { this.getFile().fromSource() }
}
private predicate hasGoodType(Expr e) {
exists(e.getType()) and not e.getType() instanceof UnknownType
}
module ExprTypeStats implements StatsSig {
int getNumberOfOk() { result = count(SourceExpr e | hasGoodType(e)) }
int getNumberOfNotOk() { result = count(SourceExpr e | not hasGoodType(e)) }
string getOkText() { result = "expressions with known type" }
string getNotOkText() { result = "expressions with unknown type" }
}
module CallTargetStatsReport = ReportStats<CallTargetStats>;
module ExprTypeStatsReport = ReportStats<ExprTypeStats>;