diff --git a/rust/ql/lib/codeql/files/FileSystem.qll b/rust/ql/lib/codeql/files/FileSystem.qll index 7136dcc3b5a..c83680f7ec6 100644 --- a/rust/ql/lib/codeql/files/FileSystem.qll +++ b/rust/ql/lib/codeql/files/FileSystem.qll @@ -6,6 +6,7 @@ private import codeql.rust.elements.SourceFile private import codeql.rust.elements.AstNode private import codeql.rust.elements.Comment private import codeql.rust.Diagnostics +private import codeql.rust.internal.ExtractorStep private module Input implements InputSig { abstract class ContainerBase extends @container { @@ -36,7 +37,9 @@ class Folder = Impl::Folder; /** A file. */ class File extends Container, Impl::File { /** Holds if this file was extracted from ordinary source code. */ - predicate fromSource() { any() } + predicate fromSource() { + exists(ExtractorStep s | s.getAction() = "Extract" and s.getFile() = this) + } /** * Gets the number of lines containing code in this file. This value @@ -58,11 +61,20 @@ class File extends Container, Impl::File { } } +/** + * A source file that was extracted. + * + * TODO: rename `SourceFile` from the generated AST to give that name to this class. + */ +class ExtractedFile extends File { + ExtractedFile() { this.fromSource() } +} + /** * A successfully extracted file, that is, a file that was extracted and * contains no extraction errors or warnings. */ -class SuccessfullyExtractedFile extends File { +class SuccessfullyExtractedFile extends ExtractedFile { SuccessfullyExtractedFile() { not exists(Diagnostic d | d.getLocation().getFile() = this and diff --git a/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll b/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll index 55505be1d59..50e6ebafebf 100644 --- a/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll +++ b/rust/ql/lib/codeql/rust/internal/ExtractorStep.qll @@ -7,7 +7,7 @@ import codeql.files.FileSystem */ class ExtractorStep extends @extractor_step { /** - * The string representation of this extractor step. + * Gets the string representation of this extractor step. */ string toString() { exists(File file, string action | @@ -17,17 +17,17 @@ class ExtractorStep extends @extractor_step { } /** - * The action this extractor step carried out. + * Gets the action this extractor step carried out. */ string getAction() { extractor_steps(this, result, _, _) } /** - * The file the extractor step was carried out on. + * Gets the file the extractor step was carried out on. */ File getFile() { extractor_steps(this, _, result, _) } /** - * The duration of the extractor step in milliseconds. + * Gets the duration of the extractor step in milliseconds. */ int getDurationMs() { extractor_steps(this, _, _, result) } diff --git a/rust/ql/src/queries/diagnostics/ExtractedFiles.ql b/rust/ql/src/queries/diagnostics/ExtractedFiles.ql index ce5aa699e67..112fb2949dc 100644 --- a/rust/ql/src/queries/diagnostics/ExtractedFiles.ql +++ b/rust/ql/src/queries/diagnostics/ExtractedFiles.ql @@ -8,6 +8,6 @@ import rust -from File f +from ExtractedFile f where exists(f.getRelativePath()) select f, "File successfully extracted." diff --git a/rust/ql/src/queries/diagnostics/ExtractionErrors.ql b/rust/ql/src/queries/diagnostics/ExtractionErrors.ql index 68be66f8ca9..bd5ec3426fb 100644 --- a/rust/ql/src/queries/diagnostics/ExtractionErrors.ql +++ b/rust/ql/src/queries/diagnostics/ExtractionErrors.ql @@ -11,7 +11,7 @@ import codeql.files.FileSystem /** Gets the SARIF severity to associate with an error. */ int getSeverity() { result = 2 } -from ExtractionError error, File f +from ExtractionError error, ExtractedFile f where f = error.getLocation().getFile() and exists(f.getRelativePath()) diff --git a/rust/ql/src/queries/summary/SummaryStats.ql b/rust/ql/src/queries/summary/SummaryStats.ql index 09ee83fc5e6..ffe7cbf1a8f 100644 --- a/rust/ql/src/queries/summary/SummaryStats.ql +++ b/rust/ql/src/queries/summary/SummaryStats.ql @@ -21,10 +21,13 @@ where or key = "Extraction warnings" and value = count(ExtractionWarning w) or - key = "Files extracted - total" and value = count(File f | exists(f.getRelativePath())) + key = "Files extracted - total" and value = count(ExtractedFile f | exists(f.getRelativePath())) or key = "Files extracted - with errors" and - value = count(File f | exists(f.getRelativePath()) and not f instanceof SuccessfullyExtractedFile) + value = + count(ExtractedFile f | + exists(f.getRelativePath()) and not f instanceof SuccessfullyExtractedFile + ) or key = "Files extracted - without errors" and value = count(SuccessfullyExtractedFile f | exists(f.getRelativePath())) diff --git a/rust/ql/test/extractor-tests/File/File.expected b/rust/ql/test/extractor-tests/File/File.expected index 924ed370b35..77fee3c3c42 100644 --- a/rust/ql/test/extractor-tests/File/File.expected +++ b/rust/ql/test/extractor-tests/File/File.expected @@ -1,3 +1,4 @@ -| a_file.rs:0:0:0:0 | a_file.rs | -| another_file.rs:0:0:0:0 | another_file.rs | -| lib.rs:0:0:0:0 | lib.rs | +| Cargo.toml:0:0:0:0 | Cargo.toml | fromSource: no | +| a_file.rs:0:0:0:0 | a_file.rs | fromSource: yes | +| another_file.rs:0:0:0:0 | another_file.rs | fromSource: yes | +| lib.rs:0:0:0:0 | lib.rs | fromSource: yes | diff --git a/rust/ql/test/extractor-tests/File/File.ql b/rust/ql/test/extractor-tests/File/File.ql index fcb2b274e78..316099193d1 100644 --- a/rust/ql/test/extractor-tests/File/File.ql +++ b/rust/ql/test/extractor-tests/File/File.ql @@ -1,5 +1,7 @@ import rust -from File f -where exists(f.getRelativePath()) -select f +from File f, string fromSource +where + exists(f.getRelativePath()) and + if f.fromSource() then fromSource = "fromSource: yes" else fromSource = "fromSource: no" +select f, fromSource diff --git a/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected b/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected index bc8dc8cccf1..c5ebb707230 100644 --- a/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/ExtractedFiles.expected @@ -5,4 +5,3 @@ | main.rs:0:0:0:0 | main.rs | File successfully extracted. | | my_macro.rs:0:0:0:0 | my_macro.rs | File successfully extracted. | | my_struct.rs:0:0:0:0 | my_struct.rs | File successfully extracted. | -| options.yml:0:0:0:0 | options.yml | File successfully extracted. | diff --git a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected index 0a58a05feed..f53c931e56e 100644 --- a/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected +++ b/rust/ql/test/query-tests/diagnostics/LinesOfUserCodeInFiles.expected @@ -5,4 +5,5 @@ | lib.rs:0:0:0:0 | lib.rs | 5 | | does_not_compile.rs:0:0:0:0 | does_not_compile.rs | 3 | | error.rs:0:0:0:0 | error.rs | 3 | +| Cargo.toml:0:0:0:0 | Cargo.toml | 0 | | options.yml:0:0:0:0 | options.yml | 0 | diff --git a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected index 74e1e461c6f..16e895cdeef 100644 --- a/rust/ql/test/query-tests/diagnostics/SummaryStats.expected +++ b/rust/ql/test/query-tests/diagnostics/SummaryStats.expected @@ -2,9 +2,9 @@ | Elements unextracted | 0 | | Extraction errors | 0 | | Extraction warnings | 7 | -| Files extracted - total | 8 | +| Files extracted - total | 7 | | Files extracted - with errors | 3 | -| Files extracted - without errors | 5 | +| Files extracted - without errors | 4 | | Inconsistencies - AST | 0 | | Inconsistencies - CFG | 0 | | Inconsistencies - data flow | 0 |