mirror of
https://github.com/github/codeql.git
synced 2026-04-26 17:25:19 +02:00
Java: add diagnostic query indicating low database quality
This commit is contained in:
65
java/ql/src/Telemetry/DatabaseQuality.qll
Normal file
65
java/ql/src/Telemetry/DatabaseQuality.qll
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Provides database quality statistics that are reported by java/telemetry/extractor-information
|
||||
* and perhaps warned about by java/diagnostics/database-quality.
|
||||
*/
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
module CallTargetStats implements StatsSig {
|
||||
int getNumberOfOk() { result = count(Call c | exists(c.getCallee())) }
|
||||
|
||||
int getNumberOfNotOk() { result = count(Call c | not exists(c.getCallee())) }
|
||||
|
||||
string getOkText() { result = "calls with call target" }
|
||||
|
||||
string getNotOkText() { result = "calls with missing call target" }
|
||||
}
|
||||
|
||||
private class SourceExpr extends Expr {
|
||||
SourceExpr() { this.getFile().isSourceFile() }
|
||||
}
|
||||
|
||||
private predicate hasGoodType(Expr e) {
|
||||
exists(e.getType()) and not e.getType() instanceof ErrorType
|
||||
}
|
||||
|
||||
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>;
|
||||
40
java/ql/src/Telemetry/DatabaseQualityDiagnostics.ql
Normal file
40
java/ql/src/Telemetry/DatabaseQualityDiagnostics.ql
Normal file
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* @name Low Java analysis quality
|
||||
* @description Low Java analysis quality
|
||||
* @kind diagnostic
|
||||
* @id java/diagnostic/database-quality
|
||||
*/
|
||||
|
||||
import java
|
||||
import DatabaseQuality
|
||||
|
||||
private newtype TDbQualityDiagnostic =
|
||||
TTheDbQualityDiagnostic() {
|
||||
exists(float percentageGood |
|
||||
CallTargetStatsReport::percentageOfOk(_, percentageGood)
|
||||
or
|
||||
ExprTypeStatsReport::percentageOfOk(_, percentageGood)
|
||||
|
|
||||
percentageGood < 95
|
||||
)
|
||||
}
|
||||
|
||||
class DbQualityDiagnostic extends TDbQualityDiagnostic {
|
||||
string toString() {
|
||||
result =
|
||||
"There were significant issues scanning Java code. " +
|
||||
"This may be caused by problems identifying dependencies or use of generated source code, among other reasons -- "
|
||||
+ "see other CodeQL diagnostics reported here for more details of possible causes. " +
|
||||
"This may lead to false-positive or missing results. Consider analysing Java using the `autobuild` or `manual` build modes."
|
||||
}
|
||||
}
|
||||
|
||||
query predicate diagnosticAttributes(DbQualityDiagnostic e, string key, string value) {
|
||||
e = e and // Quieten warning about unconstrained 'e'
|
||||
key = ["visibilityCliSummaryTable", "visibilityTelemetry", "visibilityStatusPage"] and
|
||||
value = "true"
|
||||
}
|
||||
|
||||
from DbQualityDiagnostic d
|
||||
select d, d.toString(), 1
|
||||
/* Warning severity */
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
import java
|
||||
import semmle.code.java.Diagnostics
|
||||
import DatabaseQuality
|
||||
|
||||
extensible predicate extractorInformationSkipKey(string key);
|
||||
|
||||
@@ -85,65 +86,6 @@ predicate extractorTotalDiagnostics(string key, int value) {
|
||||
)
|
||||
}
|
||||
|
||||
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.getCallee())) }
|
||||
|
||||
int getNumberOfNotOk() { result = count(Call c | not exists(c.getCallee())) }
|
||||
|
||||
string getOkText() { result = "calls with call target" }
|
||||
|
||||
string getNotOkText() { result = "calls with missing call target" }
|
||||
}
|
||||
|
||||
private class SourceExpr extends Expr {
|
||||
SourceExpr() { this.getFile().isSourceFile() }
|
||||
}
|
||||
|
||||
private predicate hasGoodType(Expr e) {
|
||||
exists(e.getType()) and not e.getType() instanceof ErrorType
|
||||
}
|
||||
|
||||
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>;
|
||||
|
||||
from string key, int value
|
||||
where
|
||||
not exists(string pattern | extractorInformationSkipKey(pattern) and key.matches(pattern)) and
|
||||
|
||||
Reference in New Issue
Block a user