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: More information about extractor errors and warnings #17647

Merged
merged 16 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions ruby/ql/consistency-queries/AstConsistency.ql
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ query predicate multipleToString(AstNode n, string s) {
}

query predicate extractionError(ExtractionError error) { any() }

query predicate extractionWarning(ExtractionWarning error) { any() }
4 changes: 4 additions & 0 deletions ruby/ql/lib/change-notes/2024-10-03-extraction-warnings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `ExtractionError` class has been split into `ExtractionError` and `ExtractionWarning`, reporting extraction errors and warnings respectively.
18 changes: 18 additions & 0 deletions ruby/ql/lib/codeql/ruby/AST.qll
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ private import ast.internal.Scope
private import ast.internal.Synthesis
private import ast.internal.TreeSitter
private import Customizations
private import Diagnostics

cached
private module Cached {
Expand Down Expand Up @@ -166,3 +167,20 @@ class RubyFile extends File {
/** Gets the number of lines of comments in this file. */
int getNumberOfLinesOfComments() { result = count(int line | this.line(line, true)) }
}

/**
* A successfully extracted file, that is, a file that was extracted and
* contains no extraction errors or warnings.
*/
class SuccessfullyExtractedFile extends File {
SuccessfullyExtractedFile() {
not exists(Diagnostic d |
d.getLocation().getFile() = this and
(
d instanceof ExtractionError
or
d instanceof ExtractionWarning
)
)
}
}
9 changes: 5 additions & 4 deletions ruby/ql/lib/codeql/ruby/Diagnostics.qll
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class Diagnostic extends @diagnostic {
string toString() { result = this.getMessage() }
}

/** A diagnostic relating to a particular error in extracting a file. */
class ExtractionError extends Diagnostic {
ExtractionError() { this.getTag() = "parse_error" }
}
/** A diagnostic that is error severity. */
class ExtractionError extends Diagnostic, @diagnostic_error { }

/** A diagnostic that is warning severity. */
class ExtractionWarning extends Diagnostic, @diagnostic_warning { }
4 changes: 4 additions & 0 deletions ruby/ql/src/change-notes/2024-10-03-extraction-warnings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `rb/diagnostics/extraction-errors` diagnostic query has been split into `rb/diagnostics/extraction-errors` and `rb/diagnostics/extraction-warnings`, counting extraction errors and warnings respectively.
19 changes: 19 additions & 0 deletions ruby/ql/src/queries/diagnostics/ExtractionWarnings.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @name Extraction warnings
* @description List all extraction warnings for files in the source code directory.
* @kind diagnostic
* @id rb/diagnostics/extraction-warnings
*/

import codeql.ruby.AST
import codeql.ruby.Diagnostics

/** Gets the SARIF severity to associate with a warning. */
int getSeverity() { result = 1 }

from ExtractionWarning warning, File f
where
f = warning.getLocation().getFile() and
exists(f.getRelativePath())
select warning, "Extraction warning in " + f + " with message " + warning.getMessage(),
getSeverity()
Comment on lines +14 to +19

Check warning

Code scanning / CodeQL

Consistent alert message Warning

The rb/diagnostics/extraction-warnings query does not have the same alert message as cpp, py.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
* @id rb/summary/number-of-files-extracted-with-errors
* @name Total number of Ruby files that were extracted with errors
* @description The total number of Ruby code files that we extracted, but where
* at least one extraction error occurred in the process.
* at least one extraction error (or warning) occurred in the process.
* @kind metric
* @tags summary
*/

import codeql.ruby.AST
import codeql.ruby.Diagnostics
import codeql.files.FileSystem

select count(File f |
exists(ExtractionError e | e.getLocation().getFile() = f) and exists(f.getRelativePath())
exists(f.getRelativePath()) and
not f instanceof SuccessfullyExtractedFile
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
* @id rb/summary/number-of-successfully-extracted-files
* @name Total number of Ruby files that were extracted without error
* @description The total number of Ruby code files that we extracted without
* encountering any extraction errors
* encountering any extraction errors (or warnings).
* @kind metric
* @tags summary
*/

import codeql.ruby.AST
import codeql.ruby.Diagnostics
import codeql.files.FileSystem

select count(File f |
not exists(ExtractionError e | e.getLocation().getFile() = f) and exists(f.getRelativePath())
)
select count(SuccessfullyExtractedFile f | exists(f.getRelativePath()))
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
extractionError
extractionWarning
| src/not_ruby.rb:5:25:5:26 | A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. |
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
| src/not_ruby.rb:5:25:5:26 | A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. | Extraction failed in src/not_ruby.rb with error A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. | 2 |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
| src/not_ruby.rb:5:25:5:26 | A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. | Extraction warning in src/not_ruby.rb with message A parse error occurred. Check the syntax of the file. If the file is invalid, correct the error or exclude the file from analysis. | 1 |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
queries/diagnostics/ExtractionWarnings.ql
2 changes: 2 additions & 0 deletions rust/ql/consistency-queries/ExtractionConsistency.ql
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import codeql.rust.Diagnostics

query predicate extractionError(ExtractionError ee) { any() }

query predicate extractionWarning(ExtractionWarning ew) { any() }
18 changes: 18 additions & 0 deletions rust/ql/lib/codeql/files/FileSystem.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ private import codeql.util.FileSystem
private import codeql.rust.elements.SourceFile
private import codeql.rust.elements.AstNode
private import codeql.rust.elements.Comment
private import codeql.rust.Diagnostics

private module Input implements InputSig {
abstract class ContainerBase extends @container {
Expand Down Expand Up @@ -56,3 +57,20 @@ class File extends Container, Impl::File {
)
}
}

/**
* A successfully extracted file, that is, a file that was extracted and
* contains no extraction errors or warnings.
*/
class SuccessfullyExtractedFile extends File {
SuccessfullyExtractedFile() {
not exists(Diagnostic d |
d.getLocation().getFile() = this and
(
d instanceof ExtractionError
or
d instanceof ExtractionWarning
)
)
}
}
9 changes: 5 additions & 4 deletions rust/ql/lib/codeql/rust/Diagnostics.qll
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class Diagnostic extends @diagnostic {
string toString() { result = this.getMessage() }
}

/** A diagnostic relating to a particular error in extracting a file. */
class ExtractionError extends Diagnostic {
ExtractionError() { this.getTag() = "parse_error" }
}
/** A diagnostic that is error severity. */
class ExtractionError extends Diagnostic, @diagnostic_error { }

/** A diagnostic that is warning severity. */
class ExtractionWarning extends Diagnostic, @diagnostic_warning { }
2 changes: 1 addition & 1 deletion rust/ql/src/queries/diagnostics/ExtractionErrors.ql
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import codeql.rust.Diagnostics
import codeql.files.FileSystem

/** Gets the SARIF severity to associate an error. */
/** Gets the SARIF severity to associate with an error. */
int getSeverity() { result = 2 }

from ExtractionError error, File f
Expand Down
19 changes: 19 additions & 0 deletions rust/ql/src/queries/diagnostics/ExtractionWarnings.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @name Extraction warnings
* @description List all extraction warnings for files in the source code directory.
* @kind diagnostic
* @id rust/diagnostics/extraction-warnings
*/

import codeql.rust.Diagnostics
import codeql.files.FileSystem

/** Gets the SARIF severity to associate with a warning. */
int getSeverity() { result = 1 }

from ExtractionWarning warning, File f
where
f = warning.getLocation().getFile() and
exists(f.getRelativePath())
select warning, "Extraction warning in " + f + " with message " + warning.getMessage(),
getSeverity()
github-advanced-security[bot] marked this conversation as resolved.
Dismissed
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
* @id rust/summary/number-of-files-extracted-with-errors
* @name Total number of Rust files that were extracted with errors
* @description The total number of Rust files in the source code directory that
* were extracted, but where at least one extraction error occurred in the process.
* were extracted, but where at least one extraction error (or warning) occurred
* in the process.
* @kind metric
* @tags summary
*/

import codeql.files.FileSystem
import codeql.rust.Diagnostics

select count(File f |
exists(ExtractionError e | e.getLocation().getFile() = f) and exists(f.getRelativePath())
exists(f.getRelativePath()) and
not f instanceof SuccessfullyExtractedFile
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
* @id rust/summary/number-of-successfully-extracted-files
* @name Total number of Rust files that were extracted without error
* @description The total number of Rust files in the source code directory that
* were extracted without encountering any extraction errors.
* were extracted without encountering any extraction errors (or warnings).
* @kind metric
* @tags summary
*/

import codeql.rust.Diagnostics
import codeql.files.FileSystem

select count(File f |
not exists(ExtractionError e | e.getLocation().getFile() = f) and exists(f.getRelativePath())
)
select count(SuccessfullyExtractedFile f | exists(f.getRelativePath()))
17 changes: 15 additions & 2 deletions rust/ql/src/queries/summary/SummaryStats.ql
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,29 @@
*/

import rust
import codeql.rust.Diagnostics
import Stats

from string key, string value
where
key = "Files extracted" and value = count(File f | exists(f.getRelativePath())).toString()
or
key = "Elements extracted" and value = count(Element e | not e instanceof Unextracted).toString()
or
key = "Elements unextracted" and value = count(Unextracted e).toString()
or
key = "Extraction errors" and value = count(ExtractionError e).toString()
or
key = "Extraction warnings" and value = count(ExtractionWarning w).toString()
or
key = "Files extracted - total" and value = count(File f | exists(f.getRelativePath())).toString()
or
key = "Files extracted - with errors" and
value =
count(File f | exists(f.getRelativePath()) and not f instanceof SuccessfullyExtractedFile)
.toString()
or
key = "Files extracted - without errors" and
value = count(SuccessfullyExtractedFile f | exists(f.getRelativePath())).toString()
or
key = "Lines of code extracted" and value = getLinesOfCode().toString()
or
key = "Lines of user code extracted" and value = getLinesOfUserCode().toString()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
extractionWarning
| lib.rs:3:9:3:8 | expected `;` or `{` |
| lib.rs:3:9:3:8 | expected an item |
| lib.rs:3:21:3:20 | expected BANG |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
extractionWarning
| does_not_compile.rs:2:6:2:5 | expected SEMICOLON |
| does_not_compile.rs:2:9:2:8 | expected SEMICOLON |
| does_not_compile.rs:2:13:2:12 | expected SEMICOLON |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +0,0 @@
| does_not_compile.rs:2:6:2:5 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 |
| does_not_compile.rs:2:9:2:8 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 |
| does_not_compile.rs:2:13:2:12 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 |
| does_not_compile.rs:2:21:2:20 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 |
| does_not_compile.rs:2:26:2:25 | expected SEMICOLON | Extraction failed in does_not_compile.rs with error expected SEMICOLON | 2 |
| does_not_compile.rs:2:32:2:31 | expected field name or number | Extraction failed in does_not_compile.rs with error expected field name or number | 2 |
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
| does_not_compile.rs:2:6:2:5 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 |
| does_not_compile.rs:2:9:2:8 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 |
| does_not_compile.rs:2:13:2:12 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 |
| does_not_compile.rs:2:21:2:20 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 |
| does_not_compile.rs:2:26:2:25 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 |
| does_not_compile.rs:2:32:2:31 | expected field name or number | Extraction warning in does_not_compile.rs with message expected field name or number | 1 |
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
queries/diagnostics/ExtractionWarnings.ql
6 changes: 5 additions & 1 deletion rust/ql/test/query-tests/diagnostics/SummaryStats.expected
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
| Elements extracted | 290 |
| Elements unextracted | 0 |
| Files extracted | 7 |
| Extraction errors | 0 |
| Extraction warnings | 6 |
| Files extracted - total | 7 |
| Files extracted - with errors | 1 |
| Files extracted - without errors | 6 |
| Lines of code extracted | 61 |
| Lines of user code extracted | 61 |
Loading