Skip to content

Commit d5f47a3

Browse files
authored
Merge pull request #15124 from tamasvajk/feature/telemetry/extraction-information
C#: Add telemetry query to report extractor information
2 parents c5cf064 + 3f843d8 commit d5f47a3

File tree

1 file changed

+195
-0
lines changed

1 file changed

+195
-0
lines changed
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/**
2+
* @name C# extraction information
3+
* @description Information about the extraction for a C# database
4+
* @kind metric
5+
* @tags summary telemetry
6+
* @id cs/telemetry/extraction-information
7+
*/
8+
9+
import csharp
10+
import semmle.code.csharp.commons.Diagnostics
11+
12+
predicate fileCount(string key, int value) {
13+
key = "Number of files" and
14+
value = strictcount(File f)
15+
}
16+
17+
predicate fileCountByExtension(string key, int value) {
18+
exists(string extension |
19+
key = "Number of files with extension " + extension and
20+
value = strictcount(File f | f.getExtension() = extension)
21+
)
22+
}
23+
24+
predicate totalNumberOfLines(string key, int value) {
25+
key = "Total number of lines" and
26+
value = strictsum(File f | any() | f.getNumberOfLines())
27+
}
28+
29+
predicate numberOfLinesOfCode(string key, int value) {
30+
key = "Number of lines of code" and
31+
value = strictsum(File f | any() | f.getNumberOfLinesOfCode())
32+
}
33+
34+
predicate totalNumberOfLinesByExtension(string key, int value) {
35+
exists(string extension |
36+
key = "Total number of lines with extension " + extension and
37+
value = strictsum(File f | f.getExtension() = extension | f.getNumberOfLines())
38+
)
39+
}
40+
41+
predicate numberOfLinesOfCodeByExtension(string key, int value) {
42+
exists(string extension |
43+
key = "Number of lines of code with extension " + extension and
44+
value = strictsum(File f | f.getExtension() = extension | f.getNumberOfLinesOfCode())
45+
)
46+
}
47+
48+
predicate extractorDiagnostics(string key, int value) {
49+
exists(int severity |
50+
key = "Number of diagnostics with severity " + severity.toString() and
51+
value = strictcount(Diagnostic d | d.getSeverity() = severity)
52+
)
53+
}
54+
55+
CompilerError getAmbiguityCompilerError() {
56+
result.getSeverity() >= 3 and
57+
result.getTag() = ["CS0101", "CS0104", "CS0111", "CS0121", "CS0229"]
58+
}
59+
60+
predicate numberOfAmbiguityCompilerErrors(string key, int value) {
61+
value = count(getAmbiguityCompilerError()) and
62+
key = "Number of compiler reported ambiguity errors"
63+
}
64+
65+
predicate numberOfDistinctAmbiguityCompilerErrorMessages(string key, int value) {
66+
value = count(getAmbiguityCompilerError().getFullMessage()) and
67+
key = "Number of compiler reported ambiguity error messages"
68+
}
69+
70+
predicate extractionIsStandalone(string key, int value) {
71+
(
72+
value = 1 and
73+
extractionIsStandalone()
74+
or
75+
value = 0 and
76+
not extractionIsStandalone()
77+
) and
78+
key = "Is buildless extraction"
79+
}
80+
81+
signature module StatsSig {
82+
int getNumberOfOk();
83+
84+
int getNumberOfNotOk();
85+
86+
string getOkText();
87+
88+
string getNotOkText();
89+
}
90+
91+
module ReportStats<StatsSig Stats> {
92+
predicate numberOfOk(string key, int value) {
93+
value = Stats::getNumberOfOk() and
94+
key = "Number of " + Stats::getOkText()
95+
}
96+
97+
predicate numberOfNotOk(string key, int value) {
98+
value = Stats::getNumberOfNotOk() and
99+
key = "Number of " + Stats::getNotOkText()
100+
}
101+
102+
predicate percentageOfOk(string key, float value) {
103+
value = Stats::getNumberOfOk() * 100.0 / (Stats::getNumberOfOk() + Stats::getNumberOfNotOk()) and
104+
key = "Percentage of " + Stats::getOkText()
105+
}
106+
}
107+
108+
module CallTargetStats implements StatsSig {
109+
int getNumberOfOk() { result = count(Call c | exists(c.getTarget())) }
110+
111+
int getNumberOfNotOk() { result = count(Call c | not exists(c.getTarget())) }
112+
113+
string getOkText() { result = "calls with call target" }
114+
115+
string getNotOkText() { result = "calls with missing call target" }
116+
}
117+
118+
module ExprTypeStats implements StatsSig {
119+
int getNumberOfOk() { result = count(Expr e | not e.getType() instanceof UnknownType) }
120+
121+
int getNumberOfNotOk() { result = count(Expr e | e.getType() instanceof UnknownType) }
122+
123+
string getOkText() { result = "expressions with known type" }
124+
125+
string getNotOkText() { result = "expressions with unknown type" }
126+
}
127+
128+
module TypeMentionTypeStats implements StatsSig {
129+
int getNumberOfOk() { result = count(TypeMention t | not t.getType() instanceof UnknownType) }
130+
131+
int getNumberOfNotOk() { result = count(TypeMention t | t.getType() instanceof UnknownType) }
132+
133+
string getOkText() { result = "type mentions with known type" }
134+
135+
string getNotOkText() { result = "type mentions with unknown type" }
136+
}
137+
138+
module AccessTargetStats implements StatsSig {
139+
int getNumberOfOk() { result = count(Access a | exists(a.getTarget())) }
140+
141+
int getNumberOfNotOk() { result = count(Access a | not exists(a.getTarget())) }
142+
143+
string getOkText() { result = "access with target" }
144+
145+
string getNotOkText() { result = "access with missing target" }
146+
}
147+
148+
module ExprStats implements StatsSig {
149+
int getNumberOfOk() { result = count(Expr e | not e instanceof @unknown_expr) }
150+
151+
int getNumberOfNotOk() { result = count(Expr e | e instanceof @unknown_expr) }
152+
153+
string getOkText() { result = "expressions with known kind" }
154+
155+
string getNotOkText() { result = "expressions with unknown kind" }
156+
}
157+
158+
module CallTargetStatsReport = ReportStats<CallTargetStats>;
159+
160+
module ExprTypeStatsReport = ReportStats<ExprTypeStats>;
161+
162+
module TypeMentionTypeStatsReport = ReportStats<TypeMentionTypeStats>;
163+
164+
module AccessTargetStatsReport = ReportStats<AccessTargetStats>;
165+
166+
module ExprStatsReport = ReportStats<ExprStats>;
167+
168+
from string key, float value
169+
where
170+
fileCount(key, value) or
171+
fileCountByExtension(key, value) or
172+
totalNumberOfLines(key, value) or
173+
numberOfLinesOfCode(key, value) or
174+
totalNumberOfLinesByExtension(key, value) or
175+
numberOfLinesOfCodeByExtension(key, value) or
176+
extractorDiagnostics(key, value) or
177+
numberOfAmbiguityCompilerErrors(key, value) or
178+
numberOfDistinctAmbiguityCompilerErrorMessages(key, value) or
179+
extractionIsStandalone(key, value) or
180+
CallTargetStatsReport::numberOfOk(key, value) or
181+
CallTargetStatsReport::numberOfNotOk(key, value) or
182+
CallTargetStatsReport::percentageOfOk(key, value) or
183+
ExprTypeStatsReport::numberOfOk(key, value) or
184+
ExprTypeStatsReport::numberOfNotOk(key, value) or
185+
ExprTypeStatsReport::percentageOfOk(key, value) or
186+
TypeMentionTypeStatsReport::numberOfOk(key, value) or
187+
TypeMentionTypeStatsReport::numberOfNotOk(key, value) or
188+
TypeMentionTypeStatsReport::percentageOfOk(key, value) or
189+
AccessTargetStatsReport::numberOfOk(key, value) or
190+
AccessTargetStatsReport::numberOfNotOk(key, value) or
191+
AccessTargetStatsReport::percentageOfOk(key, value) or
192+
ExprStatsReport::numberOfOk(key, value) or
193+
ExprStatsReport::numberOfNotOk(key, value) or
194+
ExprStatsReport::percentageOfOk(key, value)
195+
select key, value

0 commit comments

Comments
 (0)