Skip to content

Commit d8b3f3a

Browse files
authored
Merge branch 'main' into fix/actions-cache-poisoning-cache-write-access
2 parents 827af90 + 684a32b commit d8b3f3a

20 files changed

Lines changed: 2987 additions & 1399 deletions

File tree

ql/extractor/src/generator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub fn run(options: Options) -> std::io::Result<()> {
4444
languages,
4545
options.dbscheme,
4646
options.library,
47+
false, // do not use facade AST
4748
"run 'scripts/create-extractor-pack.sh' in ql/",
4849
)
4950
}

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

Lines changed: 914 additions & 422 deletions
Large diffs are not rendered by default.

ruby/extractor/src/generator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub fn run(options: Options) -> std::io::Result<()> {
3434
languages,
3535
options.dbscheme,
3636
options.library,
37+
false, // do not use facade AST
3738
"run 'make dbscheme' in ql/ruby/",
3839
)
3940
}

ruby/ql/lib/codeql/ruby/ast/internal/TreeSitter.qll

Lines changed: 970 additions & 458 deletions
Large diffs are not rendered by default.

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

Lines changed: 87 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub fn generate(
1818
languages: Vec<language::Language>,
1919
dbscheme_path: PathBuf,
2020
ql_library_path: PathBuf,
21+
use_facade_ast: bool,
2122
regenerate_instructions: &str,
2223
) -> std::io::Result<()> {
2324
let dbscheme_file = File::create(dbscheme_path).map_err(|e| {
@@ -47,6 +48,7 @@ pub fn generate(
4748
ql::write(
4849
&mut ql_writer,
4950
&[ql::TopLevel::Import(ql::Import {
51+
is_private: false,
5052
module: "codeql.Locations",
5153
alias: Some("L"),
5254
})],
@@ -122,17 +124,35 @@ pub fn generate(
122124

123125
let mut body = vec![];
124126

125-
for c in ql_gen::create_ast_node_class(
127+
let facade_import_name = if use_facade_ast {
128+
format!("FacadeAst::{}", &language.name)
129+
} else {
130+
language.name.clone() // If not using a facade AST, treat the module itself as the facade module.
131+
};
132+
if use_facade_ast {
133+
body.push(ql::TopLevel::Import(ql::Import {
134+
is_private: true,
135+
module: &facade_import_name,
136+
alias: Some("F"),
137+
}));
138+
} else {
139+
body.push(ql::TopLevel::ModuleAlias(ql::ModuleAlias {
140+
is_private: true,
141+
name: "F",
142+
target: &language.name,
143+
}));
144+
}
145+
146+
body.push(ql::TopLevel::Class(ql_gen::create_ast_node_class(
126147
&ast_node_name,
127148
&node_location_table_name,
128149
&node_parent_table_name,
129-
) {
130-
body.push(ql::TopLevel::Class(c));
131-
}
150+
)));
132151

133-
for c in ql_gen::create_token_class(&token_name, &tokeninfo_name) {
134-
body.push(ql::TopLevel::Class(c));
135-
}
152+
body.push(ql::TopLevel::Class(ql_gen::create_token_class(
153+
&token_name,
154+
&tokeninfo_name,
155+
)));
136156

137157
if has_trivia_tokens {
138158
body.push(ql::TopLevel::Class(ql_gen::create_trivia_token_class(
@@ -166,14 +186,68 @@ pub fn generate(
166186

167187
body.append(&mut ql_gen::convert_nodes(&nodes));
168188
body.push(ql_gen::create_print_ast_module(&nodes));
189+
let mut final_body = if use_facade_ast {
190+
vec![
191+
ql::TopLevel::Import(ql::Import {
192+
is_private: true,
193+
module: &facade_import_name,
194+
alias: Some("F"),
195+
}),
196+
ql::TopLevel::Import(ql::Import {
197+
is_private: false,
198+
module: "F",
199+
alias: None,
200+
}),
201+
]
202+
} else {
203+
vec![
204+
ql::TopLevel::ModuleAlias(ql::ModuleAlias {
205+
is_private: true,
206+
name: "F",
207+
target: &language.name,
208+
}),
209+
ql::TopLevel::Import(ql::Import {
210+
is_private: false,
211+
module: "F",
212+
alias: None,
213+
}),
214+
]
215+
};
216+
let final_aliases = body
217+
.iter()
218+
.filter_map(|decl| match decl {
219+
ql::TopLevel::Class(c) => Some(ql::TopLevel::Class(ql::Class {
220+
qldoc: None,
221+
name: c.name,
222+
is_abstract: false,
223+
is_final: true,
224+
is_private: false,
225+
supertypes: Set::new(),
226+
characteristic_predicate: None,
227+
predicates: vec![],
228+
alias: Some(format!("F::{}", c.name)),
229+
})),
230+
_ => None,
231+
})
232+
.collect::<Vec<_>>();
233+
final_body.extend(final_aliases);
234+
let final_module_name = format!("{}Final", language.name);
169235
ql::write(
170236
&mut ql_writer,
171-
&[ql::TopLevel::Module(ql::Module {
172-
qldoc: None,
173-
name: &language.name,
174-
body,
175-
overlay: Some(ql::OverlayAnnotation::Local),
176-
})],
237+
&[
238+
ql::TopLevel::Module(ql::Module {
239+
qldoc: None,
240+
name: &language.name,
241+
body,
242+
overlay: Some(ql::OverlayAnnotation::Local),
243+
}),
244+
ql::TopLevel::Module(ql::Module {
245+
qldoc: None,
246+
name: &final_module_name,
247+
body: final_body,
248+
overlay: None,
249+
}),
250+
],
177251
)?;
178252
}
179253
Ok(())

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::fmt;
55
pub enum TopLevel<'a> {
66
Class(Class<'a>),
77
Import(Import<'a>),
8+
ModuleAlias(ModuleAlias<'a>),
89
Module(Module<'a>),
910
Predicate(Predicate<'a>),
1011
}
@@ -14,20 +15,41 @@ impl fmt::Display for TopLevel<'_> {
1415
match self {
1516
TopLevel::Import(imp) => write!(f, "{imp}"),
1617
TopLevel::Class(cls) => write!(f, "{cls}"),
18+
TopLevel::ModuleAlias(alias) => write!(f, "{alias}"),
1719
TopLevel::Module(m) => write!(f, "{m}"),
1820
TopLevel::Predicate(pred) => write!(f, "{pred}"),
1921
}
2022
}
2123
}
2224

25+
#[derive(Clone, Eq, PartialEq, Hash)]
26+
pub struct ModuleAlias<'a> {
27+
pub is_private: bool,
28+
pub name: &'a str,
29+
pub target: &'a str,
30+
}
31+
32+
impl fmt::Display for ModuleAlias<'_> {
33+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
34+
if self.is_private {
35+
write!(f, "private ")?;
36+
}
37+
write!(f, "module {} = {};", self.name, self.target)
38+
}
39+
}
40+
2341
#[derive(Clone, Eq, PartialEq, Hash)]
2442
pub struct Import<'a> {
43+
pub is_private: bool,
2544
pub module: &'a str,
2645
pub alias: Option<&'a str>,
2746
}
2847

2948
impl fmt::Display for Import<'_> {
3049
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50+
if self.is_private {
51+
write!(f, "private ")?;
52+
}
3153
write!(f, "import {}", &self.module)?;
3254
if let Some(name) = &self.alias {
3355
write!(f, " as {name}")?;
@@ -146,6 +168,9 @@ pub enum Type<'a> {
146168

147169
/// A user-defined type.
148170
Normal(&'a str),
171+
172+
/// A normal type with an `F::` prefix.
173+
Facade(&'a str),
149174
}
150175

151176
impl fmt::Display for Type<'_> {
@@ -155,6 +180,7 @@ impl fmt::Display for Type<'_> {
155180
Type::String => write!(f, "string"),
156181
Type::Normal(name) => write!(f, "{name}"),
157182
Type::At(name) => write!(f, "@{name}"),
183+
Type::Facade(name) => write!(f, "F::{name}"),
158184
}
159185
}
160186
}

0 commit comments

Comments
 (0)