diff --git a/cli/generate/src/node_types.rs b/cli/generate/src/node_types.rs index 657f5c1f..759af5a2 100644 --- a/cli/generate/src/node_types.rs +++ b/cli/generate/src/node_types.rs @@ -918,7 +918,9 @@ mod tests { }, // This rule is not reachable from the start symbol, but // it is reachable from the 'extra_symbols' so it - // should be present in the node_types + // should be present in the node_types. + // But because it's only a literal, it will get replaced by + // a lexical variable. Variable { name: "v3".to_string(), kind: VariableType::Named, @@ -1007,6 +1009,117 @@ mod tests { ); } + #[test] + fn test_node_types_deeper_extras() { + let node_types = get_node_types(&InputGrammar { + extra_symbols: vec![Rule::named("v3")], + variables: vec![ + Variable { + name: "v1".to_string(), + kind: VariableType::Named, + rule: Rule::seq(vec![ + Rule::field("f1".to_string(), Rule::named("v2")), + Rule::field("f2".to_string(), Rule::string(";")), + ]), + }, + Variable { + name: "v2".to_string(), + kind: VariableType::Named, + rule: Rule::string("x"), + }, + // This rule is not reachable from the start symbol, but + // it is reachable from the 'extra_symbols' so it + // should be present in the node_types. + // Because it is not just a literal, it won't get replaced + // by a lexical variable. + Variable { + name: "v3".to_string(), + kind: VariableType::Named, + rule: Rule::seq(vec![Rule::string("y"), Rule::repeat(Rule::string("z"))]), + }, + ], + ..Default::default() + }); + + assert_eq!(node_types.len(), 6); + + assert_eq!( + node_types[0], + NodeInfoJSON { + kind: "v1".to_string(), + named: true, + root: true, + extra: false, + subtypes: None, + children: None, + fields: Some( + vec![ + ( + "f1".to_string(), + FieldInfoJSON { + multiple: false, + required: true, + types: vec![NodeTypeJSON { + kind: "v2".to_string(), + named: true, + }] + } + ), + ( + "f2".to_string(), + FieldInfoJSON { + multiple: false, + required: true, + types: vec![NodeTypeJSON { + kind: ";".to_string(), + named: false, + }] + } + ), + ] + .into_iter() + .collect() + ) + } + ); + assert_eq!( + node_types[1], + NodeInfoJSON { + kind: "v3".to_string(), + named: true, + root: false, + extra: true, + subtypes: None, + children: None, + fields: Some(BTreeMap::default()) + } + ); + assert_eq!( + node_types[2], + NodeInfoJSON { + kind: ";".to_string(), + named: false, + root: false, + extra: false, + subtypes: None, + children: None, + fields: None + } + ); + assert_eq!( + node_types[3], + NodeInfoJSON { + kind: "v2".to_string(), + named: true, + root: false, + extra: false, + subtypes: None, + children: None, + fields: None + } + ); + } + #[test] fn test_node_types_with_supertypes() { let node_types = get_node_types(&InputGrammar {