Skip to content

Commit 8678264

Browse files
committed
Ruby/QL: unconditionally generate discard predicates
1 parent 57b866b commit 8678264

File tree

4 files changed

+121
-25
lines changed

4 files changed

+121
-25
lines changed

ql/extractor/src/generator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@ pub fn run(options: Options) -> std::io::Result<()> {
3636
},
3737
];
3838

39-
generate(languages, options.dbscheme, options.library, false)
39+
generate(languages, options.dbscheme, options.library)
4040
}

ql/ql/src/codeql_ql/ast/internal/TreeSitter.qll

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
import codeql.Locations as L
77

8+
/** Holds if the database is an overlay. */
9+
overlay[local]
10+
private predicate isOverlay() { databaseMetadata("isOverlay", "true") }
11+
812
module QL {
913
/** The base class for all AST nodes */
1014
class AstNode extends @ql_ast_node {
@@ -48,6 +52,30 @@ module QL {
4852
final override string getAPrimaryQlClass() { result = "ReservedWord" }
4953
}
5054

55+
/** Gets the file containing the given `node`. */
56+
overlay[local]
57+
private @file getNodeFile(@ql_ast_node node) {
58+
exists(@location_default loc | ql_ast_node_location(node, loc) |
59+
locations_default(loc, result, _, _, _, _)
60+
)
61+
}
62+
63+
/** Holds if `file` was extracted as part of the overlay database. */
64+
overlay[local]
65+
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
66+
67+
/** Holds if `node` is in the `file` and is part of the overlay base database. */
68+
overlay[local]
69+
private predicate discardableAstNode(@file file, @ql_ast_node node) {
70+
not isOverlay() and file = getNodeFile(node)
71+
}
72+
73+
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
74+
overlay[discard_entity]
75+
private predicate discardAstNode(@ql_ast_node node) {
76+
exists(@file file | discardableAstNode(file, node) and discardFile(file))
77+
}
78+
5179
/** A class representing `add_expr` nodes. */
5280
class AddExpr extends @ql_add_expr, AstNode {
5381
/** Gets the name of the primary QL class for this element. */
@@ -1318,6 +1346,30 @@ module Dbscheme {
13181346
final override string getAPrimaryQlClass() { result = "ReservedWord" }
13191347
}
13201348

1349+
/** Gets the file containing the given `node`. */
1350+
overlay[local]
1351+
private @file getNodeFile(@dbscheme_ast_node node) {
1352+
exists(@location_default loc | dbscheme_ast_node_location(node, loc) |
1353+
locations_default(loc, result, _, _, _, _)
1354+
)
1355+
}
1356+
1357+
/** Holds if `file` was extracted as part of the overlay database. */
1358+
overlay[local]
1359+
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
1360+
1361+
/** Holds if `node` is in the `file` and is part of the overlay base database. */
1362+
overlay[local]
1363+
private predicate discardableAstNode(@file file, @dbscheme_ast_node node) {
1364+
not isOverlay() and file = getNodeFile(node)
1365+
}
1366+
1367+
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
1368+
overlay[discard_entity]
1369+
private predicate discardAstNode(@dbscheme_ast_node node) {
1370+
exists(@file file | discardableAstNode(file, node) and discardFile(file))
1371+
}
1372+
13211373
/** A class representing `annotName` tokens. */
13221374
class AnnotName extends @dbscheme_token_annot_name, Token {
13231375
/** Gets the name of the primary QL class for this element. */
@@ -1654,6 +1706,30 @@ module Blame {
16541706
final override string getAPrimaryQlClass() { result = "ReservedWord" }
16551707
}
16561708

1709+
/** Gets the file containing the given `node`. */
1710+
overlay[local]
1711+
private @file getNodeFile(@blame_ast_node node) {
1712+
exists(@location_default loc | blame_ast_node_location(node, loc) |
1713+
locations_default(loc, result, _, _, _, _)
1714+
)
1715+
}
1716+
1717+
/** Holds if `file` was extracted as part of the overlay database. */
1718+
overlay[local]
1719+
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
1720+
1721+
/** Holds if `node` is in the `file` and is part of the overlay base database. */
1722+
overlay[local]
1723+
private predicate discardableAstNode(@file file, @blame_ast_node node) {
1724+
not isOverlay() and file = getNodeFile(node)
1725+
}
1726+
1727+
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
1728+
overlay[discard_entity]
1729+
private predicate discardAstNode(@blame_ast_node node) {
1730+
exists(@file file | discardableAstNode(file, node) and discardFile(file))
1731+
}
1732+
16571733
/** A class representing `blame_entry` nodes. */
16581734
class BlameEntry extends @blame_blame_entry, AstNode {
16591735
/** Gets the name of the primary QL class for this element. */
@@ -1767,6 +1843,30 @@ module JSON {
17671843
final override string getAPrimaryQlClass() { result = "ReservedWord" }
17681844
}
17691845

1846+
/** Gets the file containing the given `node`. */
1847+
overlay[local]
1848+
private @file getNodeFile(@json_ast_node node) {
1849+
exists(@location_default loc | json_ast_node_location(node, loc) |
1850+
locations_default(loc, result, _, _, _, _)
1851+
)
1852+
}
1853+
1854+
/** Holds if `file` was extracted as part of the overlay database. */
1855+
overlay[local]
1856+
private predicate discardFile(@file file) { isOverlay() and file = getNodeFile(_) }
1857+
1858+
/** Holds if `node` is in the `file` and is part of the overlay base database. */
1859+
overlay[local]
1860+
private predicate discardableAstNode(@file file, @json_ast_node node) {
1861+
not isOverlay() and file = getNodeFile(node)
1862+
}
1863+
1864+
/** Holds if `node` should be discarded, because it is part of the overlay base and is in a file that was also extracted as part of the overlay database. */
1865+
overlay[discard_entity]
1866+
private predicate discardAstNode(@json_ast_node node) {
1867+
exists(@file file | discardableAstNode(file, node) and discardFile(file))
1868+
}
1869+
17701870
class UnderscoreValue extends @json_underscore_value, AstNode { }
17711871

17721872
/** A class representing `array` nodes. */

ruby/extractor/src/generator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,5 @@ pub fn run(options: Options) -> std::io::Result<()> {
2828
},
2929
];
3030

31-
generate(languages, options.dbscheme, options.library, true)
31+
generate(languages, options.dbscheme, options.library)
3232
}

shared/tree-sitter-extractor/src/generator/mod.rs

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ pub fn generate(
1717
languages: Vec<language::Language>,
1818
dbscheme_path: PathBuf,
1919
ql_library_path: PathBuf,
20-
overlay_support: bool,
2120
) -> std::io::Result<()> {
2221
let dbscheme_file = File::create(dbscheme_path).map_err(|e| {
2322
tracing::error!("Failed to create dbscheme file: {}", e);
@@ -50,14 +49,12 @@ pub fn generate(
5049
})],
5150
)?;
5251

53-
if overlay_support {
54-
ql::write(
55-
&mut ql_writer,
56-
&[ql::TopLevel::Predicate(
57-
ql_gen::create_is_overlay_predicate(),
58-
)],
59-
)?;
60-
}
52+
ql::write(
53+
&mut ql_writer,
54+
&[ql::TopLevel::Predicate(
55+
ql_gen::create_is_overlay_predicate(),
56+
)],
57+
)?;
6158

6259
for language in languages {
6360
let prefix = node_types::to_snake_case(&language.name);
@@ -103,20 +100,19 @@ pub fn generate(
103100
ql::TopLevel::Class(ql_gen::create_reserved_word_class(&reserved_word_name)),
104101
];
105102

106-
if overlay_support {
107-
body.push(ql::TopLevel::Predicate(
108-
ql_gen::create_get_node_file_predicate(&ast_node_name, &node_location_table_name),
109-
));
110-
body.push(ql::TopLevel::Predicate(
111-
ql_gen::create_discard_file_predicate(),
112-
));
113-
body.push(ql::TopLevel::Predicate(
114-
ql_gen::create_discardable_ast_node_predicate(&ast_node_name),
115-
));
116-
body.push(ql::TopLevel::Predicate(
117-
ql_gen::create_discard_ast_node_predicate(&ast_node_name),
118-
));
119-
}
103+
// Overlay discard predicates
104+
body.push(ql::TopLevel::Predicate(
105+
ql_gen::create_get_node_file_predicate(&ast_node_name, &node_location_table_name),
106+
));
107+
body.push(ql::TopLevel::Predicate(
108+
ql_gen::create_discard_file_predicate(),
109+
));
110+
body.push(ql::TopLevel::Predicate(
111+
ql_gen::create_discardable_ast_node_predicate(&ast_node_name),
112+
));
113+
body.push(ql::TopLevel::Predicate(
114+
ql_gen::create_discard_ast_node_predicate(&ast_node_name),
115+
));
120116

121117
body.append(&mut ql_gen::convert_nodes(&nodes));
122118
ql::write(

0 commit comments

Comments
 (0)