Skip to content

Commit

Permalink
Merge pull request #18697 from hvitved/rust/telemetry
Browse files Browse the repository at this point in the history
Rust: Implement database quality telemetry query
  • Loading branch information
hvitved authored Feb 7, 2025
2 parents b5c0754 + 11bf4c8 commit 614b3ce
Show file tree
Hide file tree
Showing 6 changed files with 185 additions and 54 deletions.
28 changes: 1 addition & 27 deletions csharp/ql/src/Telemetry/DatabaseQuality.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,7 @@
*/

import csharp

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()
}
}
import codeql.util.ReportStats

module CallTargetStats implements StatsSig {
int getNumberOfOk() { result = count(Call c | exists(c.getTarget())) }
Expand Down
28 changes: 1 addition & 27 deletions java/ql/src/Telemetry/DatabaseQuality.qll
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,7 @@
*/

import java

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()
}
}
import codeql.util.ReportStats

module CallTargetStats implements StatsSig {
int getNumberOfOk() { result = count(Call c | exists(c.getCallee())) }
Expand Down
46 changes: 46 additions & 0 deletions rust/ql/src/queries/telemetry/DatabaseQuality.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* Provides database quality statistics that are reported by
* `rust/telemetry/extractor-information`
* and perhaps warned about by `rust/diagnostics/database-quality`.
*/

import rust
import codeql.util.ReportStats

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

private predicate isLambdaCall(CallExpr call) {
exists(Expr receiver | receiver = call.getFunction() |
// All calls to complex expressions and local variable accesses are lambda calls
receiver instanceof PathExpr implies receiver = any(Variable v).getAnAccess()
)
}

additional predicate isNotOkCall(CallExprBase c) {
not exists(c.getStaticTarget()) and
not isLambdaCall(c)
}

int getNumberOfNotOk() { result = count(CallExprBase c | isNotOkCall(c)) }

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

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

module MacroCallTargetStats implements StatsSig {
int getNumberOfOk() { result = count(MacroCall c | c.hasExpanded()) }

additional predicate isNotOkCall(MacroCall c) { not c.hasExpanded() }

int getNumberOfNotOk() { result = count(MacroCall c | isNotOkCall(c)) }

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

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

module CallTargetStatsReport = ReportStats<CallTargetStats>;

module MacroCallTargetStatsReport = ReportStats<MacroCallTargetStats>;
41 changes: 41 additions & 0 deletions rust/ql/src/queries/telemetry/DatabaseQualityDiagnostics.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @name Low Rust analysis quality
* @description Low Rust analysis quality
* @kind diagnostic
* @id rust/diagnostic/database-quality
*/

import rust
import DatabaseQuality
import codeql.util.Unit

class DbQualityDiagnostic extends Unit {
DbQualityDiagnostic() {
exists(float percentageGood |
CallTargetStatsReport::percentageOfOk(_, percentageGood)
or
MacroCallTargetStatsReport::percentageOfOk(_, percentageGood)
|
percentageGood < 95
)
}

string toString() {
result =
"Scanning Rust code completed successfully, but the scan encountered issues. " +
"This may be caused by problems identifying dependencies or use of generated source code, among other reasons -- "
+
"see other CodeQL diagnostics reported on the CodeQL status page for more details of possible causes. "
+ "Addressing these warnings is advisable to avoid false-positive or missing results."
}
}

query predicate diagnosticAttributes(DbQualityDiagnostic e, string key, string value) {
exists(e) and // Quieten warning about unconstrained 'e'
key = ["visibilityCliSummaryTable", "visibilityTelemetry", "visibilityStatusPage"] and
value = "true"
}

from DbQualityDiagnostic d
select d, d.toString(), 1
/* 1 = Warning severity */
65 changes: 65 additions & 0 deletions rust/ql/src/queries/telemetry/ExtractorInformation.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* @name Rust extraction information
* @description Information about the extraction for a Rust database
* @kind metric
* @tags summary telemetry
* @id rust/telemetry/extraction-information
*/

import rust
import DatabaseQuality
import codeql.rust.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 numberOfLinesOfCode(string key, int value) {
key = "Number of lines of code" and
value = strictsum(File f | any() | f.getNumberOfLinesOfCode())
}

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)
)
}

from string key, float value
where
(
fileCount(key, value) or
fileCountByExtension(key, value) or
numberOfLinesOfCode(key, value) or
numberOfLinesOfCodeByExtension(key, value) or
extractorDiagnostics(key, value) or
CallTargetStatsReport::numberOfOk(key, value) or
CallTargetStatsReport::numberOfNotOk(key, value) or
CallTargetStatsReport::percentageOfOk(key, value) or
MacroCallTargetStatsReport::numberOfOk(key, value) or
MacroCallTargetStatsReport::numberOfNotOk(key, value) or
MacroCallTargetStatsReport::percentageOfOk(key, value)
) and
/* Infinity */
value != 1.0 / 0.0 and
/* -Infinity */
value != -1.0 / 0.0 and
/* NaN */
value != 0.0 / 0.0
select key, value
31 changes: 31 additions & 0 deletions shared/util/codeql/util/ReportStats.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Provides the `ReportStats` module for reporting database quality statistics.
*/
module;

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()
}
}

0 comments on commit 614b3ce

Please sign in to comment.