From a2bbc7391bf6215694e5a7e94f445b49f3107996 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 13 Nov 2019 10:38:47 -0800 Subject: [PATCH] node-types: Fix handling of simple aliased inlined rules --- cli/src/generate/mod.rs | 3 +- cli/src/generate/node_types.rs | 74 +++++++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 7 deletions(-) diff --git a/cli/src/generate/mod.rs b/cli/src/generate/mod.rs index 0644e2cd..866fa78b 100644 --- a/cli/src/generate/mod.rs +++ b/cli/src/generate/mod.rs @@ -149,7 +149,8 @@ fn generate_parser_for_grammar_with_opts( next_abi: bool, report_symbol_name: Option<&str>, ) -> Result { - let variable_info = node_types::get_variable_info(&syntax_grammar, &lexical_grammar)?; + let variable_info = + node_types::get_variable_info(&syntax_grammar, &lexical_grammar, &simple_aliases)?; let node_types_json = node_types::generate_node_types_json( &syntax_grammar, &lexical_grammar, diff --git a/cli/src/generate/node_types.rs b/cli/src/generate/node_types.rs index 59594d89..a145c93b 100644 --- a/cli/src/generate/node_types.rs +++ b/cli/src/generate/node_types.rs @@ -137,6 +137,7 @@ impl ChildQuantity { pub(crate) fn get_variable_info( syntax_grammar: &SyntaxGrammar, lexical_grammar: &LexicalGrammar, + simple_aliases: &AliasMap, ) -> Result> { let child_type_is_visible = |t: &ChildType| { variable_type_for_child_type(t, syntax_grammar, lexical_grammar) >= VariableType::Anonymous @@ -174,6 +175,8 @@ pub(crate) fn get_variable_info( let child_symbol = step.symbol; let child_type = if let Some(alias) = &step.alias { ChildType::Aliased(alias.clone()) + } else if let Some(alias) = simple_aliases.get(&step.symbol) { + ChildType::Aliased(alias.clone()) } else { ChildType::Normal(child_symbol) }; @@ -223,8 +226,7 @@ pub(crate) fn get_variable_info( if child_symbol.is_non_terminal() && !syntax_grammar.supertype_symbols.contains(&child_symbol) && step.alias.is_none() - && (!child_type_is_visible(&child_type) - || syntax_grammar.variables_to_inline.contains(&child_symbol)) + && !child_type_is_visible(&child_type) { let child_variable_info = &result[child_symbol.index]; @@ -345,7 +347,7 @@ pub(crate) fn get_variable_info( } // Update all of the node type lists to account for node visiblity: - // * Wherever possible, repalce lists of subtypes with their supertypes. + // * Wherever possible, replace lists of subtypes with their supertypes. // * Remove other hidden node types. for i in 0..result.len() { let mut variable_info = VariableInfo::default(); @@ -398,7 +400,9 @@ fn variable_type_for_child_type( } ChildType::Normal(symbol) => { if syntax_grammar.supertype_symbols.contains(&symbol) { - return VariableType::Named; + VariableType::Named + } else if syntax_grammar.variables_to_inline.contains(&symbol) { + VariableType::Hidden } else { match symbol.kind { SymbolType::NonTerminal => syntax_grammar.variables[symbol.index].kind, @@ -956,6 +960,61 @@ mod tests { ); } + #[test] + fn test_node_types_with_inlined_rules() { + let node_types = get_node_types(InputGrammar { + name: String::new(), + word_token: None, + extra_symbols: Vec::new(), + external_tokens: Vec::new(), + expected_conflicts: Vec::new(), + variables_to_inline: vec!["v2".to_string()], + supertype_symbols: vec![], + variables: vec![ + Variable { + name: "v1".to_string(), + kind: VariableType::Named, + rule: Rule::seq(vec![Rule::named("v2"), Rule::named("v3")]), + }, + // v2 should not appear in the node types, since it is inlined + Variable { + name: "v2".to_string(), + kind: VariableType::Named, + rule: Rule::alias(Rule::string("a"), "x".to_string(), true), + }, + Variable { + name: "v3".to_string(), + kind: VariableType::Named, + rule: Rule::string("b"), + }, + ], + }); + + assert_eq!( + node_types[0], + NodeInfoJSON { + kind: "v1".to_string(), + named: true, + subtypes: None, + children: Some(FieldInfoJSON { + multiple: true, + required: true, + types: vec![ + NodeTypeJSON { + kind: "v3".to_string(), + named: true, + }, + NodeTypeJSON { + kind: "x".to_string(), + named: true, + }, + ] + }), + fields: Some(BTreeMap::new()), + } + ); + } + #[test] fn test_node_types_for_aliased_nodes() { let node_types = get_node_types(InputGrammar { @@ -1158,6 +1217,7 @@ mod tests { vec![], ), &build_lexical_grammar(), + &AliasMap::new(), ) .unwrap(); @@ -1238,6 +1298,7 @@ mod tests { vec![], ), &build_lexical_grammar(), + &AliasMap::new(), ) .unwrap(); @@ -1258,7 +1319,6 @@ mod tests { .collect::>() ); - // assert_eq!( variable_info[0].children_without_fields, FieldInfo { @@ -1312,6 +1372,7 @@ mod tests { vec![Symbol::non_terminal(1)], ), &build_lexical_grammar(), + &AliasMap::new(), ) .unwrap(); @@ -1336,7 +1397,8 @@ mod tests { fn get_node_types(grammar: InputGrammar) -> Vec { let (syntax_grammar, lexical_grammar, _, simple_aliases) = prepare_grammar(&grammar).unwrap(); - let variable_info = get_variable_info(&syntax_grammar, &lexical_grammar).unwrap(); + let variable_info = + get_variable_info(&syntax_grammar, &lexical_grammar, &simple_aliases).unwrap(); generate_node_types_json( &syntax_grammar, &lexical_grammar,