mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Tree-sitter: Split up ast_node_info table into two tables
This commit is contained in:
@@ -209,10 +209,10 @@ struct Visitor<'a> {
|
||||
diagnostics_writer: &'a mut diagnostics::LogWriter,
|
||||
/// A trap::Writer to accumulate trap entries
|
||||
trap_writer: &'a mut trap::Writer,
|
||||
/// A counter for top-level child nodes
|
||||
toplevel_child_counter: usize,
|
||||
/// Language-specific name of the AST info table
|
||||
ast_node_info_table_name: String,
|
||||
/// Language-specific name of the AST location table
|
||||
ast_node_location_table_name: String,
|
||||
/// Language-specific name of the AST parent table
|
||||
ast_node_parent_table_name: String,
|
||||
/// Language-specific name of the tokeninfo table
|
||||
tokeninfo_table_name: String,
|
||||
/// A lookup table from type name to node types
|
||||
@@ -242,8 +242,8 @@ impl<'a> Visitor<'a> {
|
||||
source,
|
||||
diagnostics_writer,
|
||||
trap_writer,
|
||||
toplevel_child_counter: 0,
|
||||
ast_node_info_table_name: format!("{}_ast_node_info", language_prefix),
|
||||
ast_node_location_table_name: format!("{}_ast_node_location", language_prefix),
|
||||
ast_node_parent_table_name: format!("{}_ast_node_parent", language_prefix),
|
||||
tokeninfo_table_name: format!("{}_tokeninfo", language_prefix),
|
||||
schema,
|
||||
stack: Vec::new(),
|
||||
@@ -342,27 +342,29 @@ impl<'a> Visitor<'a> {
|
||||
})
|
||||
.unwrap();
|
||||
let mut valid = true;
|
||||
let (parent_id, parent_index) = match self.stack.last_mut() {
|
||||
let parent_info = match self.stack.last_mut() {
|
||||
Some(p) if !node.is_extra() => {
|
||||
p.1 += 1;
|
||||
(p.0, p.1 - 1)
|
||||
}
|
||||
_ => {
|
||||
self.toplevel_child_counter += 1;
|
||||
(self.file_label, self.toplevel_child_counter - 1)
|
||||
Some((p.0, p.1 - 1))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
match &table.kind {
|
||||
EntryKind::Token { kind_id, .. } => {
|
||||
self.trap_writer.add_tuple(
|
||||
&self.ast_node_info_table_name,
|
||||
vec![
|
||||
trap::Arg::Label(id),
|
||||
trap::Arg::Label(parent_id),
|
||||
trap::Arg::Int(parent_index),
|
||||
trap::Arg::Label(loc_label),
|
||||
],
|
||||
&self.ast_node_location_table_name,
|
||||
vec![trap::Arg::Label(id), trap::Arg::Label(loc_label)],
|
||||
);
|
||||
if let Some((parent_id, parent_index)) = parent_info {
|
||||
self.trap_writer.add_tuple(
|
||||
&self.ast_node_parent_table_name,
|
||||
vec![
|
||||
trap::Arg::Label(id),
|
||||
trap::Arg::Label(parent_id),
|
||||
trap::Arg::Int(parent_index),
|
||||
],
|
||||
);
|
||||
};
|
||||
self.trap_writer.add_tuple(
|
||||
&self.tokeninfo_table_name,
|
||||
vec![
|
||||
@@ -378,14 +380,19 @@ impl<'a> Visitor<'a> {
|
||||
} => {
|
||||
if let Some(args) = self.complex_node(&node, fields, &child_nodes, id) {
|
||||
self.trap_writer.add_tuple(
|
||||
&self.ast_node_info_table_name,
|
||||
vec![
|
||||
trap::Arg::Label(id),
|
||||
trap::Arg::Label(parent_id),
|
||||
trap::Arg::Int(parent_index),
|
||||
trap::Arg::Label(loc_label),
|
||||
],
|
||||
&self.ast_node_location_table_name,
|
||||
vec![trap::Arg::Label(id), trap::Arg::Label(loc_label)],
|
||||
);
|
||||
if let Some((parent_id, parent_index)) = parent_info {
|
||||
self.trap_writer.add_tuple(
|
||||
&self.ast_node_parent_table_name,
|
||||
vec![
|
||||
trap::Arg::Label(id),
|
||||
trap::Arg::Label(parent_id),
|
||||
trap::Arg::Int(parent_index),
|
||||
],
|
||||
);
|
||||
};
|
||||
let mut all_args = vec![trap::Arg::Label(id)];
|
||||
all_args.extend(args);
|
||||
self.trap_writer.add_tuple(table_name, all_args);
|
||||
|
||||
@@ -52,8 +52,8 @@ pub fn generate(
|
||||
for language in languages {
|
||||
let prefix = node_types::to_snake_case(&language.name);
|
||||
let ast_node_name = format!("{}_ast_node", &prefix);
|
||||
let node_info_table_name = format!("{}_ast_node_info", &prefix);
|
||||
let ast_node_parent_name = format!("{}_ast_node_parent", &prefix);
|
||||
let node_location_table_name = format!("{}_ast_node_location", &prefix);
|
||||
let node_parent_table_name = format!("{}_ast_node_parent", &prefix);
|
||||
let token_name = format!("{}_token", &prefix);
|
||||
let tokeninfo_name = format!("{}_tokeninfo", &prefix);
|
||||
let reserved_word_name = format!("{}_reserved_word", &prefix);
|
||||
@@ -72,13 +72,12 @@ pub fn generate(
|
||||
name: &ast_node_name,
|
||||
members: ast_node_members,
|
||||
}),
|
||||
dbscheme::Entry::Union(dbscheme::Union {
|
||||
name: &ast_node_parent_name,
|
||||
members: [&ast_node_name, "file"].iter().cloned().collect(),
|
||||
}),
|
||||
dbscheme::Entry::Table(create_ast_node_info_table(
|
||||
&node_info_table_name,
|
||||
&ast_node_parent_name,
|
||||
dbscheme::Entry::Table(create_ast_node_location_table(
|
||||
&node_location_table_name,
|
||||
&ast_node_name,
|
||||
)),
|
||||
dbscheme::Entry::Table(create_ast_node_parent_table(
|
||||
&node_parent_table_name,
|
||||
&ast_node_name,
|
||||
)),
|
||||
],
|
||||
@@ -87,7 +86,8 @@ pub fn generate(
|
||||
let mut body = vec![
|
||||
ql::TopLevel::Class(ql_gen::create_ast_node_class(
|
||||
&ast_node_name,
|
||||
&node_info_table_name,
|
||||
&node_location_table_name,
|
||||
&node_parent_table_name,
|
||||
)),
|
||||
ql::TopLevel::Class(ql_gen::create_token_class(&token_name, &tokeninfo_name)),
|
||||
ql::TopLevel::Class(ql_gen::create_reserved_word_class(&reserved_word_name)),
|
||||
@@ -335,18 +335,43 @@ fn convert_nodes(
|
||||
(entries, ast_node_members, token_kinds)
|
||||
}
|
||||
|
||||
/// Creates a dbscheme table specifying the parent node and location for each
|
||||
/// AST node.
|
||||
/// Creates a dbscheme table specifying the location for each AST node.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `name` - the name of the table to create.
|
||||
/// - `parent_name` - the name of the parent type.
|
||||
/// - `ast_node_name` - the name of the node child type.
|
||||
fn create_ast_node_info_table<'a>(
|
||||
fn create_ast_node_location_table<'a>(
|
||||
name: &'a str,
|
||||
parent_name: &'a str,
|
||||
ast_node_name: &'a str,
|
||||
) -> dbscheme::Table<'a> {
|
||||
dbscheme::Table {
|
||||
name,
|
||||
columns: vec![
|
||||
dbscheme::Column {
|
||||
db_type: dbscheme::DbColumnType::Int,
|
||||
name: "node",
|
||||
unique: true,
|
||||
ql_type: ql::Type::At(ast_node_name),
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
dbscheme::Column {
|
||||
unique: false,
|
||||
db_type: dbscheme::DbColumnType::Int,
|
||||
name: "loc",
|
||||
ql_type: ql::Type::At("location_default"),
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
],
|
||||
keysets: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a dbscheme table specifying the parent node for each AST node.
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `name` - the name of the table to create.
|
||||
/// - `ast_node_name` - the name of the node child type.
|
||||
fn create_ast_node_parent_table<'a>(name: &'a str, ast_node_name: &'a str) -> dbscheme::Table<'a> {
|
||||
dbscheme::Table {
|
||||
name,
|
||||
columns: vec![
|
||||
@@ -361,7 +386,7 @@ fn create_ast_node_info_table<'a>(
|
||||
db_type: dbscheme::DbColumnType::Int,
|
||||
name: "parent",
|
||||
unique: false,
|
||||
ql_type: ql::Type::At(parent_name),
|
||||
ql_type: ql::Type::At(ast_node_name),
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
dbscheme::Column {
|
||||
@@ -371,13 +396,6 @@ fn create_ast_node_info_table<'a>(
|
||||
ql_type: ql::Type::Int,
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
dbscheme::Column {
|
||||
unique: false,
|
||||
db_type: dbscheme::DbColumnType::Int,
|
||||
name: "loc",
|
||||
ql_type: ql::Type::At("location_default"),
|
||||
ql_type_is_ref: true,
|
||||
},
|
||||
],
|
||||
keysets: Some(vec!["parent", "parent_index"]),
|
||||
}
|
||||
|
||||
@@ -4,7 +4,11 @@ use crate::{generator::ql, node_types};
|
||||
|
||||
/// Creates the hard-coded `AstNode` class that acts as a supertype of all
|
||||
/// classes we generate.
|
||||
pub fn create_ast_node_class<'a>(ast_node: &'a str, node_info_table: &'a str) -> ql::Class<'a> {
|
||||
pub fn create_ast_node_class<'a>(
|
||||
ast_node: &'a str,
|
||||
node_location_table: &'a str,
|
||||
node_parent_table: &'a str,
|
||||
) -> ql::Class<'a> {
|
||||
// Default implementation of `toString` calls `this.getAPrimaryQlClass()`
|
||||
let to_string = ql::Predicate {
|
||||
qldoc: Some(String::from(
|
||||
@@ -32,13 +36,8 @@ pub fn create_ast_node_class<'a>(ast_node: &'a str, node_info_table: &'a str) ->
|
||||
return_type: Some(ql::Type::Normal("L::Location")),
|
||||
formal_parameters: vec![],
|
||||
body: ql::Expression::Pred(
|
||||
node_info_table,
|
||||
vec![
|
||||
ql::Expression::Var("this"),
|
||||
ql::Expression::Var("_"), // parent
|
||||
ql::Expression::Var("_"), // parent index
|
||||
ql::Expression::Var("result"), // location
|
||||
],
|
||||
node_location_table,
|
||||
vec![ql::Expression::Var("this"), ql::Expression::Var("result")],
|
||||
),
|
||||
};
|
||||
let get_a_field_or_child = create_none_predicate(
|
||||
@@ -55,12 +54,11 @@ pub fn create_ast_node_class<'a>(ast_node: &'a str, node_info_table: &'a str) ->
|
||||
return_type: Some(ql::Type::Normal("AstNode")),
|
||||
formal_parameters: vec![],
|
||||
body: ql::Expression::Pred(
|
||||
node_info_table,
|
||||
node_parent_table,
|
||||
vec![
|
||||
ql::Expression::Var("this"),
|
||||
ql::Expression::Var("result"),
|
||||
ql::Expression::Var("_"), // parent index
|
||||
ql::Expression::Var("_"), // location
|
||||
ql::Expression::Var("_"),
|
||||
],
|
||||
),
|
||||
};
|
||||
@@ -74,12 +72,11 @@ pub fn create_ast_node_class<'a>(ast_node: &'a str, node_info_table: &'a str) ->
|
||||
return_type: Some(ql::Type::Int),
|
||||
formal_parameters: vec![],
|
||||
body: ql::Expression::Pred(
|
||||
node_info_table,
|
||||
node_parent_table,
|
||||
vec![
|
||||
ql::Expression::Var("this"),
|
||||
ql::Expression::Var("_"), // parent
|
||||
ql::Expression::Var("result"), // parent index
|
||||
ql::Expression::Var("_"), // location
|
||||
ql::Expression::Var("_"),
|
||||
ql::Expression::Var("result"),
|
||||
],
|
||||
),
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user