Skip to content

Commit 3c6fc14

Browse files
committed
yeast-schema: Track leaf node kinds
The `rules!` macro needs this information to decide whether a bare output node should inherit the value of the matched input node.
1 parent 73c6b40 commit 3c6fc14

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

‎shared/yeast-schema/src/node_types_yaml.rs‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ fn apply_yaml_to_schema(yaml: &YamlNodeTypes, schema: &mut crate::schema::Schema
361361
// Register named node kinds and their fields
362362
for (name, fields_opt) in &yaml.named {
363363
schema.register_kind(name);
364+
schema.set_leaf_kind(name, fields_opt.as_ref().map_or(true, BTreeMap::is_empty));
364365
register_fields(schema, fields_opt.as_ref());
365366
}
366367
for supertype in yaml.supertypes.values() {
@@ -810,6 +811,36 @@ unnamed:
810811
assert_eq!(end["named"], false);
811812
}
812813

814+
#[test]
815+
fn test_leaf_kinds_are_recorded_in_schema() {
816+
let schema = schema_from_yaml(
817+
r#"
818+
named:
819+
identifier:
820+
empty_fields: {}
821+
call:
822+
callee: identifier
823+
"#,
824+
)
825+
.unwrap();
826+
827+
assert!(schema.is_leaf_kind("identifier"));
828+
assert!(schema.is_leaf_kind("empty_fields"));
829+
assert!(!schema.is_leaf_kind("call"));
830+
831+
let mut schema = schema;
832+
extend_schema_from_yaml(
833+
&mut schema,
834+
r#"
835+
named:
836+
identifier:
837+
child: empty_fields
838+
"#,
839+
)
840+
.unwrap();
841+
assert!(!schema.is_leaf_kind("identifier"));
842+
}
843+
813844
#[test]
814845
fn test_explicit_unnamed_disambiguation() {
815846
let yaml = r#"

‎shared/yeast-schema/src/schema.rs‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ pub struct Schema {
4444
field_types: BTreeMap<(String, FieldId), Vec<NodeType>>,
4545
field_cardinalities: BTreeMap<(String, FieldId), FieldCardinality>,
4646
supertypes: BTreeMap<String, Vec<NodeType>>,
47+
leaf_kinds: BTreeSet<String>,
4748
/// Per-node-kind declared field order (named fields only), as written in
4849
/// the source node-types YAML. Field ids are not a stable ordering key
4950
/// across front-ends, so this preserves the authored order for
@@ -70,6 +71,7 @@ impl Schema {
7071
field_types: BTreeMap::new(),
7172
field_cardinalities: BTreeMap::new(),
7273
supertypes: BTreeMap::new(),
74+
leaf_kinds: BTreeSet::new(),
7375
field_order: BTreeMap::new(),
7476
}
7577
}
@@ -347,6 +349,20 @@ impl Schema {
347349
self.supertypes.contains_key(kind)
348350
}
349351

352+
pub(crate) fn set_leaf_kind(&mut self, kind: &str, is_leaf: bool) {
353+
if is_leaf {
354+
self.leaf_kinds.insert(kind.to_string());
355+
} else {
356+
// TODO: This is only needed for schema extensions. Consider removing
357+
// extension support, after which non-leaf kinds can simply be ignored.
358+
self.leaf_kinds.remove(kind);
359+
}
360+
}
361+
362+
pub fn is_leaf_kind(&self, kind: &str) -> bool {
363+
self.leaf_kinds.contains(kind)
364+
}
365+
350366
fn allows_node(
351367
&self,
352368
node_type: &NodeType,

0 commit comments

Comments
 (0)