Skip to content
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

Rust: Count number of AST inconsistencies #17774

Merged
merged 9 commits into from
Oct 16, 2024
29 changes: 8 additions & 21 deletions rust/ql/consistency-queries/AstConsistency.ql
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
import rust
import codeql.rust.elements.internal.generated.ParentChild

query predicate multipleToString(Element e, string s) {
s = strictconcat(e.toString(), ",") and
strictcount(e.toString()) > 1
}

query predicate multipleLocations(Locatable e) { strictcount(e.getLocation()) > 1 }

query predicate multiplePrimaryQlClasses(Element e, string s) {
s = e.getPrimaryQlClasses() and
strictcount(e.getAPrimaryQlClass()) > 1
}

private Element getParent(Element child) { child = getChildAndAccessor(result, _, _) }

query predicate multipleParents(Element child, Element parent) {
parent = getParent(child) and
strictcount(getParent(child)) > 1
}
/**
* @name Abstract syntax tree inconsistencies
* @description Lists the abstract syntax tree inconsistencies in the database. This query is intended for internal use.
* @kind table
* @id rust/diagnostics/ast-consistency
*/

import codeql.rust.AstConsistency
7 changes: 7 additions & 0 deletions rust/ql/consistency-queries/ExtractionConsistency.ql
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* @name Extraction consistency
* @description Lists the extraction inconsistencies (errors) in the database. This query is intended for internal use.
* @kind table
* @id rust/diagnostics/extraction-consistency
*/

import codeql.rust.Diagnostics

query predicate extractionError(ExtractionError ee) { any() }
Expand Down
55 changes: 55 additions & 0 deletions rust/ql/lib/codeql/rust/AstConsistency.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Provides classes for recognizing control flow graph inconsistencies.
*/

private import rust
private import codeql.rust.elements.internal.generated.ParentChild

/**
* Holds if `e` has more than one `toString()` result.
*/
query predicate multipleToStrings(Element e, string s) {
s = strictconcat(e.toString(), ", ") and
strictcount(e.toString()) > 1
}

/**
* Holds if `e` has more than one `Location`.
*/
query predicate multipleLocations(Locatable e) { strictcount(e.getLocation()) > 1 }

/**
* Holds if `e` has more than one `getPrimaryQlClasses()` result.
*/
query predicate multiplePrimaryQlClasses(Element e, string s) {
s = strictconcat(e.getPrimaryQlClasses(), ", ") and
strictcount(e.getAPrimaryQlClass()) > 1
}

private Element getParent(Element child) { child = getChildAndAccessor(result, _, _) }

/**
* Holds if `child` has more than one AST parent.
*/
query predicate multipleParents(Element child, Element parent) {
parent = getParent(child) and
strictcount(getParent(child)) > 1
}

/**
* Gets counts of abstract syntax tree inconsistencies of each type.
*/
int getAstInconsistencyCounts(string type) {
// total results from all the AST consistency query predicates.
type = "Multiple toStrings" and
result = count(Element e | multipleToStrings(e, _) | e)
or
type = "Multiple locations" and
result = count(Element e | multipleLocations(e) | e)
or
type = "Multiple primary QL classes" and
result = count(Element e | multiplePrimaryQlClasses(e, _) | e)
or
type = "Multiple parents" and
result = count(Element e | multipleParents(e, _) | e)
}
15 changes: 15 additions & 0 deletions rust/ql/src/queries/diagnostics/AstConsistencyCounts.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* @name Abstract syntax tree inconsistency counts
* @description Counts the number of abstract syntax tree inconsistencies of each type. This query is intended for internal use.
* @kind diagnostic
* @id rust/diagnostics/ast-consistency-counts
*/

import rust
import codeql.rust.AstConsistency as Consistency

// see also `rust/diagnostics/ast-consistency`, which lists the
// individual inconsistency results.
from string type, int num
where num = Consistency::getAstInconsistencyCounts(type)
select type, num
8 changes: 8 additions & 0 deletions rust/ql/src/queries/summary/Stats.qll
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

import rust
import codeql.rust.AstConsistency as AstConsistency
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency

/**
Expand All @@ -17,6 +18,13 @@ int getLinesOfUserCode() {
result = sum(File f | exists(f.getRelativePath()) | f.getNumberOfLinesOfCode())
}

/**
* Gets a count of the total number of abstract syntax tree inconsistencies in the database.
*/
int getTotalAstInconsistencies() {
result = sum(string type | | AstConsistency::getAstInconsistencyCounts(type))
}

/**
* Gets a count of the total number of control flow graph inconsistencies in the database.
*/
Expand Down
28 changes: 14 additions & 14 deletions rust/ql/src/queries/summary/SummaryStats.ql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @name Summary Statistics
* @description A table of summary statistics about a database.
* @kind table
* @kind metric
* @id rust/summary/summary-statistics
* @tags summary
*/
Expand All @@ -10,29 +10,29 @@ import rust
import codeql.rust.Diagnostics
import Stats

from string key, string value
from string key, int value
where
key = "Elements extracted" and value = count(Element e | not e instanceof Unextracted).toString()
key = "Elements extracted" and value = count(Element e | not e instanceof Unextracted)
or
key = "Elements unextracted" and value = count(Unextracted e).toString()
key = "Elements unextracted" and value = count(Unextracted e)
or
key = "Extraction errors" and value = count(ExtractionError e).toString()
key = "Extraction errors" and value = count(ExtractionError e)
or
key = "Extraction warnings" and value = count(ExtractionWarning w).toString()
key = "Extraction warnings" and value = count(ExtractionWarning w)
or
key = "Files extracted - total" and value = count(File f | exists(f.getRelativePath())).toString()
key = "Files extracted - total" and value = count(File f | exists(f.getRelativePath()))
or
key = "Files extracted - with errors" and
value =
count(File f | exists(f.getRelativePath()) and not f instanceof SuccessfullyExtractedFile)
.toString()
value = count(File f | exists(f.getRelativePath()) and not f instanceof SuccessfullyExtractedFile)
or
key = "Files extracted - without errors" and
value = count(SuccessfullyExtractedFile f | exists(f.getRelativePath())).toString()
value = count(SuccessfullyExtractedFile f | exists(f.getRelativePath()))
or
key = "Lines of code extracted" and value = getLinesOfCode().toString()
key = "Lines of code extracted" and value = getLinesOfCode()
or
key = "Lines of user code extracted" and value = getLinesOfUserCode().toString()
key = "Lines of user code extracted" and value = getLinesOfUserCode()
or
key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies().toString()
key = "Inconsistencies - AST" and value = getTotalAstInconsistencies()
or
key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies()
select key, value
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
| Multiple locations | 0 |
| Multiple parents | 0 |
| Multiple primary QL classes | 0 |
| Multiple toStrings | 0 |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
queries/diagnostics/AstConsistencyCounts.ql
1 change: 1 addition & 0 deletions rust/ql/test/query-tests/diagnostics/SummaryStats.expected
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
| Files extracted - total | 7 |
| Files extracted - with errors | 2 |
| Files extracted - without errors | 5 |
| Inconsistencies - AST | 0 |
| Inconsistencies - CFG | 0 |
| Lines of code extracted | 59 |
| Lines of user code extracted | 59 |
Loading