Skip to content

Commit de9aa42

Browse files
authored
Merge pull request #22519 from aschackmull/yeast/keep-child-order
Yeast: Keep AST iteration order as in ast_types.yml.
2 parents ec8b097 + b3b559e commit de9aa42

2 files changed

Lines changed: 44 additions & 13 deletions

File tree

shared/yeast-schema/src/schema.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ pub struct Schema {
4747
/// Per-node-kind declared field order (named fields only), as written in
4848
/// the source node-types YAML. Field ids are not a stable ordering key
4949
/// across front-ends, so this preserves the authored order for
50-
/// presentation (see the AST dump).
50+
/// presentation (see the AST dump) and tree traversal during extraction.
5151
field_order: BTreeMap<String, Vec<FieldId>>,
5252
}
5353

@@ -193,6 +193,17 @@ impl Schema {
193193
for name in other.field_ids.keys() {
194194
self.register_field(name);
195195
}
196+
for (kind, order) in &other.field_order {
197+
let order = order
198+
.iter()
199+
.filter_map(|&field_id| {
200+
other
201+
.field_name_for_id(field_id)
202+
.map(|name| self.register_field(name))
203+
})
204+
.collect();
205+
self.set_field_order(kind, order);
206+
}
196207
}
197208

198209
/// Track a name for a kind ID without registering it as named or

shared/yeast/src/lib.rs

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ impl<'a> AstCursor<'a> {
323323
fn goto_first_child_opt(&mut self) -> Option<()> {
324324
let parent_id = self.node_id;
325325
let parent = self.ast.get_node(parent_id)?;
326-
let mut children = ChildrenIter::new(parent);
326+
let mut children = ChildrenIter::new(self.ast, parent);
327327
let first_child = children.next()?;
328328
self.node_id = first_child;
329329
self.parents.push((parent_id, children));
@@ -340,15 +340,35 @@ impl<'a> AstCursor<'a> {
340340
#[derive(Debug)]
341341
struct ChildrenIter<'a> {
342342
current_field: Option<FieldId>,
343-
fields: std::collections::btree_map::Iter<'a, FieldId, Vec<Id>>,
343+
fields: &'a BTreeMap<FieldId, Vec<Id>>,
344+
field_order: std::vec::IntoIter<FieldId>,
344345
field_children: Option<std::slice::Iter<'a, Id>>,
345346
}
346347

347348
impl<'a> ChildrenIter<'a> {
348-
fn new(node: &'a Node) -> Self {
349+
fn new(ast: &'a Ast, node: &'a Node) -> Self {
350+
let fields = &node.fields;
351+
let present: Vec<FieldId> = fields.keys().copied().collect();
352+
let field_order = match ast.schema.field_order(node.kind_name()) {
353+
Some(order) => {
354+
let mut fields: Vec<FieldId> = order
355+
.iter()
356+
.copied()
357+
.filter(|field| fields.contains_key(field))
358+
.collect();
359+
for field in present {
360+
if !fields.contains(&field) {
361+
fields.push(field);
362+
}
363+
}
364+
fields.into_iter()
365+
}
366+
None => present.into_iter(),
367+
};
349368
Self {
350369
current_field: None,
351-
fields: node.fields.iter(),
370+
fields,
371+
field_order,
352372
field_children: None,
353373
}
354374
}
@@ -363,20 +383,20 @@ impl Iterator for ChildrenIter<'_> {
363383

364384
fn next(&mut self) -> Option<Self::Item> {
365385
match self.field_children.as_mut() {
366-
None => match self.fields.next() {
367-
Some((field, children)) => {
368-
self.current_field = Some(*field);
369-
self.field_children = Some(children.iter());
386+
None => match self.field_order.next() {
387+
Some(field) => {
388+
self.current_field = Some(field);
389+
self.field_children = Some(self.fields[&field].iter());
370390
self.next()
371391
}
372392
None => None,
373393
},
374394
Some(children) => match children.next() {
375-
None => match self.fields.next() {
395+
None => match self.field_order.next() {
376396
None => None,
377-
Some((field, children)) => {
378-
self.current_field = Some(*field);
379-
self.field_children = Some(children.iter());
397+
Some(field) => {
398+
self.current_field = Some(field);
399+
self.field_children = Some(self.fields[&field].iter());
380400
self.next()
381401
}
382402
},

0 commit comments

Comments
 (0)