Skip to content

C#: Add telemetry query to report extractor information #15124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 195 additions & 0 deletions csharp/ql/src/Telemetry/ExtractorInformation.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
/**
* @name C# extraction information
* @description Information about the extraction for a C# database
* @kind metric
* @tags summary telemetry
* @id cs/telemetry/extraction-information
*/

import csharp
import semmle.code.csharp.commons.Diagnostics

predicate fileCount(string key, int value) {
key = "Number of files" and
value = strictcount(File f)
}

predicate fileCountByExtension(string key, int value) {
exists(string extension |
key = "Number of files with extension " + extension and
value = strictcount(File f | f.getExtension() = extension)
)
}

predicate totalNumberOfLines(string key, int value) {
key = "Total number of lines" and
value = strictsum(File f | any() | f.getNumberOfLines())
}

predicate numberOfLinesOfCode(string key, int value) {
key = "Number of lines of code" and
value = strictsum(File f | any() | f.getNumberOfLinesOfCode())
}

predicate totalNumberOfLinesByExtension(string key, int value) {
exists(string extension |
key = "Total number of lines with extension " + extension and
value = strictsum(File f | f.getExtension() = extension | f.getNumberOfLines())
)
}

predicate numberOfLinesOfCodeByExtension(string key, int value) {
exists(string extension |
key = "Number of lines of code with extension " + extension and
value = strictsum(File f | f.getExtension() = extension | f.getNumberOfLinesOfCode())
)
}

predicate extractorDiagnostics(string key, int value) {
exists(int severity |
key = "Number of diagnostics with severity " + severity.toString() and
value = strictcount(Diagnostic d | d.getSeverity() = severity)
)
}

CompilerError getAmbiguityCompilerError() {
result.getSeverity() >= 3 and
result.getTag() = ["CS0101", "CS0104", "CS0111", "CS0121", "CS0229"]
}

predicate numberOfAmbiguityCompilerErrors(string key, int value) {
value = count(getAmbiguityCompilerError()) and
key = "Number of compiler reported ambiguity errors"
}

predicate numberOfDistinctAmbiguityCompilerErrorMessages(string key, int value) {
value = count(getAmbiguityCompilerError().getFullMessage()) and
key = "Number of compiler reported ambiguity error messages"
}

predicate extractionIsStandalone(string key, int value) {
(
value = 1 and
extractionIsStandalone()
or
value = 0 and
not extractionIsStandalone()
) and
key = "Is buildless extraction"
}

signature module StatsSig {
int getNumberOfOk();

int getNumberOfNotOk();

string getOkText();

string getNotOkText();
}

module ReportStats<StatsSig Stats> {
predicate numberOfOk(string key, int value) {
value = Stats::getNumberOfOk() and
key = "Number of " + Stats::getOkText()
}

predicate numberOfNotOk(string key, int value) {
value = Stats::getNumberOfNotOk() and
key = "Number of " + Stats::getNotOkText()
}

predicate percentageOfOk(string key, float value) {
value = Stats::getNumberOfOk() * 100.0 / (Stats::getNumberOfOk() + Stats::getNumberOfNotOk()) and
key = "Percentage of " + Stats::getOkText()
}
}

module CallTargetStats implements StatsSig {
int getNumberOfOk() { result = count(Call c | exists(c.getTarget())) }

int getNumberOfNotOk() { result = count(Call c | not exists(c.getTarget())) }

string getOkText() { result = "calls with call target" }

string getNotOkText() { result = "calls with missing call target" }
}

module ExprTypeStats implements StatsSig {
int getNumberOfOk() { result = count(Expr e | not e.getType() instanceof UnknownType) }

int getNumberOfNotOk() { result = count(Expr e | e.getType() instanceof UnknownType) }

string getOkText() { result = "expressions with known type" }

string getNotOkText() { result = "expressions with unknown type" }
}

module TypeMentionTypeStats implements StatsSig {
int getNumberOfOk() { result = count(TypeMention t | not t.getType() instanceof UnknownType) }

int getNumberOfNotOk() { result = count(TypeMention t | t.getType() instanceof UnknownType) }

string getOkText() { result = "type mentions with known type" }

string getNotOkText() { result = "type mentions with unknown type" }
}

module AccessTargetStats implements StatsSig {
int getNumberOfOk() { result = count(Access a | exists(a.getTarget())) }

int getNumberOfNotOk() { result = count(Access a | not exists(a.getTarget())) }

string getOkText() { result = "access with target" }

string getNotOkText() { result = "access with missing target" }
}

module ExprStats implements StatsSig {
int getNumberOfOk() { result = count(Expr e | not e instanceof @unknown_expr) }

Check warning

Code scanning / CodeQL

Use of database type outside the language core

Database type used outside the language lib/ folder.

int getNumberOfNotOk() { result = count(Expr e | e instanceof @unknown_expr) }

Check warning

Code scanning / CodeQL

Use of database type outside the language core

Database type used outside the language lib/ folder.

string getOkText() { result = "expressions with known kind" }

string getNotOkText() { result = "expressions with unknown kind" }
}

module CallTargetStatsReport = ReportStats<CallTargetStats>;

module ExprTypeStatsReport = ReportStats<ExprTypeStats>;

module TypeMentionTypeStatsReport = ReportStats<TypeMentionTypeStats>;

module AccessTargetStatsReport = ReportStats<AccessTargetStats>;

module ExprStatsReport = ReportStats<ExprStats>;

from string key, float value
where
fileCount(key, value) or
fileCountByExtension(key, value) or
totalNumberOfLines(key, value) or
numberOfLinesOfCode(key, value) or
totalNumberOfLinesByExtension(key, value) or
numberOfLinesOfCodeByExtension(key, value) or
extractorDiagnostics(key, value) or
numberOfAmbiguityCompilerErrors(key, value) or
numberOfDistinctAmbiguityCompilerErrorMessages(key, value) or
extractionIsStandalone(key, value) or
CallTargetStatsReport::numberOfOk(key, value) or
CallTargetStatsReport::numberOfNotOk(key, value) or
CallTargetStatsReport::percentageOfOk(key, value) or
ExprTypeStatsReport::numberOfOk(key, value) or
ExprTypeStatsReport::numberOfNotOk(key, value) or
ExprTypeStatsReport::percentageOfOk(key, value) or
TypeMentionTypeStatsReport::numberOfOk(key, value) or
TypeMentionTypeStatsReport::numberOfNotOk(key, value) or
TypeMentionTypeStatsReport::percentageOfOk(key, value) or
AccessTargetStatsReport::numberOfOk(key, value) or
AccessTargetStatsReport::numberOfNotOk(key, value) or
AccessTargetStatsReport::percentageOfOk(key, value) or
ExprStatsReport::numberOfOk(key, value) or
ExprStatsReport::numberOfNotOk(key, value) or
ExprStatsReport::percentageOfOk(key, value)
select key, value