Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e181666

Browse files
authored
Merge pull request #49 from github/aibaars/parent
Add parent ref and parent_index fields to all AstNodes
2 parents c7b07b7 + 0836727 commit e181666

5 files changed

Lines changed: 951 additions & 270 deletions

File tree

extractor/src/extractor.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ impl Extractor {
188188
path: format!("{}", path.display()),
189189
file_label: *file_label,
190190
token_counter: 0,
191+
toplevel_child_counter: 0,
191192
stack: Vec::new(),
192193
schema: &self.schema,
193194
};
@@ -257,14 +258,17 @@ struct Visitor<'a> {
257258
trap_writer: TrapWriter,
258259
/// A counter for tokens
259260
token_counter: usize,
261+
/// A counter for top-level child nodes
262+
toplevel_child_counter: usize,
260263
/// A lookup table from type name to node types
261264
schema: &'a NodeTypeMap,
262-
/// A stack for gathering information from hild nodes. Whenever a node is entered
263-
/// an empty list is pushed. All children append their data (field name, label, type) to
264-
/// the the list. When the visitor leaves a node the list containing the child data is popped
265-
/// from the stack and matched against the dbscheme for the node. If the expectations are met
266-
/// the corresponding row definitions are added to the trap_output.
267-
stack: Vec<Vec<(Option<&'static str>, Label, TypeName)>>,
265+
/// A stack for gathering information from child nodes. Whenever a node is entered
266+
/// the parent's [Label], child counter, and an empty list is pushed. All children append their data
267+
/// (field name, label, type) to the the list. When the visitor leaves a node the list
268+
/// containing the child data is popped from the stack and matched against the dbscheme
269+
/// for the node. If the expectations are met the corresponding row definitions are
270+
/// added to the trap_output.
271+
stack: Vec<(Label, usize, Vec<(Option<&'static str>, Label, TypeName)>)>,
268272
}
269273

270274
impl Visitor<'_> {
@@ -287,19 +291,20 @@ impl Visitor<'_> {
287291
return false;
288292
}
289293

290-
self.stack.push(Vec::new());
294+
let id = self.trap_writer.fresh_id();
295+
296+
self.stack.push((id, 0, Vec::new()));
291297
return true;
292298
}
293299

294300
fn leave_node(&mut self, field_name: Option<&'static str>, node: Node) {
295301
if node.is_error() || node.is_missing() {
296302
return;
297303
}
298-
let child_nodes = self.stack.pop().expect("Vistor: empty stack");
299-
let id = self.trap_writer.fresh_id();
304+
let (id, _, child_nodes) = self.stack.pop().expect("Vistor: empty stack");
300305
let (start_line, start_column, end_line, end_column) = location_for(&self.source, node);
301306
let loc = self.trap_writer.location(
302-
self.file_label.clone(),
307+
self.file_label,
303308
start_line,
304309
start_column,
305310
end_line,
@@ -313,12 +318,24 @@ impl Visitor<'_> {
313318
})
314319
.unwrap();
315320
let mut valid = true;
321+
let (parent_id, parent_index) = match self.stack.last_mut() {
322+
Some(p) if !node.is_extra() => {
323+
p.1 += 1;
324+
(p.0, p.1 - 1)
325+
}
326+
_ => {
327+
self.toplevel_child_counter += 1;
328+
(self.file_label, self.toplevel_child_counter - 1)
329+
}
330+
};
316331
match &table.kind {
317332
EntryKind::Token { kind_id, .. } => {
318333
self.trap_writer.add_tuple(
319334
"tokeninfo",
320335
vec![
321336
Arg::Label(id),
337+
Arg::Label(parent_id),
338+
Arg::Int(parent_index),
322339
Arg::Int(*kind_id),
323340
Arg::Label(self.file_label),
324341
Arg::Int(self.token_counter),
@@ -335,6 +352,8 @@ impl Visitor<'_> {
335352
if let Some(args) = self.complex_node(&node, fields, child_nodes, id) {
336353
let mut all_args = Vec::new();
337354
all_args.push(Arg::Label(id));
355+
all_args.push(Arg::Label(parent_id));
356+
all_args.push(Arg::Int(parent_index));
338357
all_args.extend(args);
339358
all_args.push(Arg::Label(loc));
340359
self.trap_writer.add_tuple(&table_name, all_args);
@@ -354,7 +373,7 @@ impl Visitor<'_> {
354373
// Extra nodes are independent root nodes and do not belong to the parent node
355374
// Therefore we should not register them in the parent vector
356375
if let Some(parent) = self.stack.last_mut() {
357-
parent.push((
376+
parent.2.push((
358377
field_name,
359378
id,
360379
TypeName {

generator/src/main.rs

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<dbscheme::Entry<
136136
})
137137
.collect();
138138
ast_node_members.insert("token");
139-
140139
for (_, node) in nodes {
141140
match &node.kind {
142141
node_types::EntryKind::Union { members: n_members } => {
@@ -155,14 +154,30 @@ fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<dbscheme::Entry<
155154
// It's a product type, defined by a table.
156155
let mut main_table = dbscheme::Table {
157156
name: &name,
158-
columns: vec![dbscheme::Column {
159-
db_type: dbscheme::DbColumnType::Int,
160-
name: "id",
161-
unique: true,
162-
ql_type: ql::Type::AtType(&node.dbscheme_name),
163-
ql_type_is_ref: false,
164-
}],
165-
keysets: None,
157+
columns: vec![
158+
dbscheme::Column {
159+
db_type: dbscheme::DbColumnType::Int,
160+
name: "id",
161+
unique: true,
162+
ql_type: ql::Type::AtType(&node.dbscheme_name),
163+
ql_type_is_ref: false,
164+
},
165+
dbscheme::Column {
166+
db_type: dbscheme::DbColumnType::Int,
167+
name: "parent",
168+
unique: false,
169+
ql_type: ql::Type::AtType("ast_node_parent"),
170+
ql_type_is_ref: true,
171+
},
172+
dbscheme::Column {
173+
unique: false,
174+
db_type: dbscheme::DbColumnType::Int,
175+
name: "parent_index",
176+
ql_type: ql::Type::Int,
177+
ql_type_is_ref: true,
178+
},
179+
],
180+
keysets: Some(vec!["parent", "parent_index"]),
166181
};
167182
ast_node_members.insert(&node.dbscheme_name);
168183

@@ -227,6 +242,11 @@ fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<dbscheme::Entry<
227242
members: ast_node_members,
228243
}));
229244

245+
// Create the ast_node_parent union.
246+
entries.push(dbscheme::Entry::Union(dbscheme::Union {
247+
name: "ast_node_parent",
248+
members: ["ast_node", "file"].iter().cloned().collect(),
249+
}));
230250
entries
231251
}
232252

@@ -235,7 +255,7 @@ fn create_tokeninfo<'a>(
235255
) -> (dbscheme::Case<'a>, dbscheme::Table<'a>) {
236256
let table = dbscheme::Table {
237257
name: "tokeninfo",
238-
keysets: None,
258+
keysets: Some(vec!["parent", "parent_index"]),
239259
columns: vec![
240260
dbscheme::Column {
241261
db_type: dbscheme::DbColumnType::Int,
@@ -244,6 +264,20 @@ fn create_tokeninfo<'a>(
244264
ql_type: ql::Type::AtType("token"),
245265
ql_type_is_ref: false,
246266
},
267+
dbscheme::Column {
268+
db_type: dbscheme::DbColumnType::Int,
269+
name: "parent",
270+
unique: false,
271+
ql_type: ql::Type::AtType("ast_node_parent"),
272+
ql_type_is_ref: true,
273+
},
274+
dbscheme::Column {
275+
unique: false,
276+
db_type: dbscheme::DbColumnType::Int,
277+
name: "parent_index",
278+
ql_type: ql::Type::Int,
279+
ql_type_is_ref: true,
280+
},
247281
dbscheme::Column {
248282
unique: false,
249283
db_type: dbscheme::DbColumnType::Int,

generator/src/ql_gen.rs

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -46,31 +46,8 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
4646
create_none_predicate("getLocation", false, Some(ql::Type::Normal("Location")));
4747
let get_a_field_or_child =
4848
create_none_predicate("getAFieldOrChild", false, Some(ql::Type::Normal("AstNode")));
49-
let get_parent = ql::Predicate {
50-
name: "getParent",
51-
overridden: false,
52-
return_type: Some(ql::Type::Normal("AstNode")),
53-
formal_parameters: vec![],
54-
body: ql::Expression::Equals(
55-
Box::new(ql::Expression::Var("result")),
56-
Box::new(ql::Expression::Aggregate(
57-
"unique",
58-
vec![ql::FormalParameter {
59-
name: "parent",
60-
param_type: ql::Type::Normal("AstNode"),
61-
}],
62-
Box::new(ql::Expression::Equals(
63-
Box::new(ql::Expression::Var("this")),
64-
Box::new(ql::Expression::Dot(
65-
Box::new(ql::Expression::Var("parent")),
66-
"getAFieldOrChild",
67-
vec![],
68-
)),
69-
)),
70-
Box::new(ql::Expression::Var("parent")),
71-
)),
72-
),
73-
};
49+
let get_parent = create_none_predicate("getParent", false, Some(ql::Type::Normal("AstNode")));
50+
let get_parent_index = create_none_predicate("getParentIndex", false, Some(ql::Type::Int));
7451
let describe_ql_class = ql::Predicate {
7552
name: "describeQlClass",
7653
overridden: false,
@@ -90,46 +67,41 @@ fn create_ast_node_class<'a>() -> ql::Class<'a> {
9067
to_string,
9168
get_location,
9269
get_parent,
70+
get_parent_index,
9371
get_a_field_or_child,
9472
describe_ql_class,
9573
],
9674
}
9775
}
9876

9977
fn create_token_class<'a>() -> ql::Class<'a> {
78+
let get_parent = ql::Predicate {
79+
name: "getParent",
80+
overridden: true,
81+
return_type: Some(ql::Type::Normal("AstNode")),
82+
formal_parameters: vec![],
83+
body: create_get_field_expr_for_column_storage("tokeninfo", 0, 8),
84+
};
85+
let get_parent_index = ql::Predicate {
86+
name: "getParentIndex",
87+
overridden: true,
88+
return_type: Some(ql::Type::Int),
89+
formal_parameters: vec![],
90+
body: create_get_field_expr_for_column_storage("tokeninfo", 1, 8),
91+
};
10092
let get_value = ql::Predicate {
10193
name: "getValue",
10294
overridden: false,
10395
return_type: Some(ql::Type::String),
10496
formal_parameters: vec![],
105-
body: ql::Expression::Pred(
106-
"tokeninfo",
107-
vec![
108-
ql::Expression::Var("this"),
109-
ql::Expression::Var("_"),
110-
ql::Expression::Var("_"),
111-
ql::Expression::Var("_"),
112-
ql::Expression::Var("result"),
113-
ql::Expression::Var("_"),
114-
],
115-
),
97+
body: create_get_field_expr_for_column_storage("tokeninfo", 5, 8),
11698
};
11799
let get_location = ql::Predicate {
118100
name: "getLocation",
119101
overridden: true,
120102
return_type: Some(ql::Type::Normal("Location")),
121103
formal_parameters: vec![],
122-
body: ql::Expression::Pred(
123-
"tokeninfo",
124-
vec![
125-
ql::Expression::Var("this"),
126-
ql::Expression::Var("_"),
127-
ql::Expression::Var("_"),
128-
ql::Expression::Var("_"),
129-
ql::Expression::Var("_"),
130-
ql::Expression::Var("result"),
131-
],
132-
),
104+
body: create_get_field_expr_for_column_storage("tokeninfo", 6, 8),
133105
};
134106
let to_string = ql::Predicate {
135107
name: "toString",
@@ -149,6 +121,8 @@ fn create_token_class<'a>() -> ql::Class<'a> {
149121
.collect(),
150122
characteristic_predicate: None,
151123
predicates: vec![
124+
get_parent,
125+
get_parent_index,
152126
get_value,
153127
get_location,
154128
to_string,
@@ -262,7 +236,7 @@ fn create_get_field_expr_for_column_storage<'a>(
262236
column_index: usize,
263237
arity: usize,
264238
) -> ql::Expression<'a> {
265-
let num_underscores_before = column_index - 1;
239+
let num_underscores_before = column_index;
266240
let num_underscores_after = arity - 2 - num_underscores_before;
267241
ql::Expression::Pred(
268242
table_name,
@@ -436,10 +410,12 @@ pub fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<ql::TopLevel
436410
// Count how many columns there will be in the main table.
437411
// There will be:
438412
// - one for the id
413+
// - one for the parent
414+
// - one for the parent index
439415
// - one for the location
440416
// - one for each field that's stored as a column
441417
// - if there are no fields, one for the text column.
442-
let main_table_arity = 2 + if fields.is_empty() {
418+
let main_table_arity = 4 + if fields.is_empty() {
443419
1
444420
} else {
445421
fields
@@ -470,7 +446,7 @@ pub fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<ql::TopLevel
470446
.predicates
471447
.push(create_get_text_predicate(&main_table_name));
472448
} else {
473-
let mut main_table_column_index: usize = 1;
449+
let mut main_table_column_index: usize = 2;
474450
let mut get_child_exprs: Vec<ql::Expression> = Vec::new();
475451

476452
// Iterate through the fields, creating:
@@ -489,6 +465,30 @@ pub fn convert_nodes<'a>(nodes: &'a node_types::NodeTypeMap) -> Vec<ql::TopLevel
489465
get_child_exprs.push(get_child_expr);
490466
}
491467

468+
main_class.predicates.push(ql::Predicate {
469+
name: "getParent",
470+
overridden: true,
471+
return_type: Some(ql::Type::Normal("AstNode")),
472+
formal_parameters: vec![],
473+
body: create_get_field_expr_for_column_storage(
474+
&main_table_name,
475+
0,
476+
main_table_arity,
477+
),
478+
});
479+
480+
main_class.predicates.push(ql::Predicate {
481+
name: "getParentIndex",
482+
overridden: true,
483+
return_type: Some(ql::Type::Int),
484+
formal_parameters: vec![],
485+
body: create_get_field_expr_for_column_storage(
486+
&main_table_name,
487+
1,
488+
main_table_arity,
489+
),
490+
});
491+
492492
main_class.predicates.push(ql::Predicate {
493493
name: "getAFieldOrChild",
494494
overridden: true,

0 commit comments

Comments
 (0)