From e9afdd72b44d022067adf8fa83b35070f26401b5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 26 Mar 2019 15:27:07 -0700 Subject: [PATCH] node-types: Fix incorrect `named` value for subclasses --- cli/src/generate/build_tables/mod.rs | 4 +- cli/src/generate/node_types.rs | 174 ++++++++++++++++++++++++++- 2 files changed, 173 insertions(+), 5 deletions(-) diff --git a/cli/src/generate/build_tables/mod.rs b/cli/src/generate/build_tables/mod.rs index 7f8b1a45..4b357f47 100644 --- a/cli/src/generate/build_tables/mod.rs +++ b/cli/src/generate/build_tables/mod.rs @@ -1,5 +1,5 @@ -mod build_lex_table; -mod build_parse_table; +pub(crate) mod build_lex_table; +pub(crate) mod build_parse_table; mod coincident_tokens; mod item; mod item_set_builder; diff --git a/cli/src/generate/node_types.rs b/cli/src/generate/node_types.rs index 35129189..f9aa1738 100644 --- a/cli/src/generate/node_types.rs +++ b/cli/src/generate/node_types.rs @@ -53,21 +53,21 @@ pub(crate) fn generate_node_types_json( let variable = &syntax_grammar.variables[symbol.index]; NodeTypeJSON { kind: variable.name.clone(), - named: variable.kind == VariableType::Named, + named: variable.kind != VariableType::Anonymous, } } SymbolType::Terminal => { let variable = &lexical_grammar.variables[symbol.index]; NodeTypeJSON { kind: variable.name.clone(), - named: variable.kind == VariableType::Named, + named: variable.kind != VariableType::Anonymous, } } SymbolType::External => { let variable = &syntax_grammar.external_tokens[symbol.index]; NodeTypeJSON { kind: variable.name.clone(), - named: variable.kind == VariableType::Named, + named: variable.kind != VariableType::Anonymous, } } _ => panic!("Unexpected symbol type"), @@ -131,3 +131,171 @@ pub(crate) fn generate_node_types_json( node_types_json.into_iter().map(|e| e.1).collect() } + +#[cfg(test)] +mod tests { + use super::*; + use crate::generate::build_tables::build_parse_table::get_variable_info; + use crate::generate::grammars::{InputGrammar, Variable, VariableType}; + use crate::generate::prepare_grammar::prepare_grammar; + use crate::generate::rules::Rule; + + #[test] + fn test_node_types_simple() { + let node_types = get_node_types(InputGrammar { + name: String::new(), + extra_tokens: Vec::new(), + external_tokens: Vec::new(), + expected_conflicts: Vec::new(), + variables_to_inline: Vec::new(), + word_token: None, + supertype_symbols: vec![], + 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"), + }, + ], + }); + + assert_eq!( + node_types[0], + NodeInfoJSON { + name: "v1".to_string(), + subtypes: 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() + ) + } + ); + } + + #[test] + fn test_node_types_with_supertypes() { + let node_types = get_node_types(InputGrammar { + name: String::new(), + extra_tokens: Vec::new(), + external_tokens: Vec::new(), + expected_conflicts: Vec::new(), + variables_to_inline: Vec::new(), + word_token: None, + supertype_symbols: vec!["_v2".to_string()], + variables: vec![ + Variable { + name: "v1".to_string(), + kind: VariableType::Named, + rule: Rule::field("f1".to_string(), Rule::named("_v2")), + }, + Variable { + name: "_v2".to_string(), + kind: VariableType::Hidden, + rule: Rule::choice(vec![ + Rule::named("v3"), + Rule::named("v4"), + Rule::string("*"), + ]), + }, + Variable { + name: "v3".to_string(), + kind: VariableType::Named, + rule: Rule::string("x"), + }, + Variable { + name: "v4".to_string(), + kind: VariableType::Named, + rule: Rule::string("y"), + }, + ], + }); + + assert_eq!( + node_types[0], + NodeInfoJSON { + name: "_v2".to_string(), + fields: None, + subtypes: Some(vec![ + NodeTypeJSON { + kind: "*".to_string(), + named: false, + }, + NodeTypeJSON { + kind: "v3".to_string(), + named: true, + }, + NodeTypeJSON { + kind: "v4".to_string(), + named: true, + }, + ]), + } + ); + assert_eq!( + node_types[1], + NodeInfoJSON { + name: "v1".to_string(), + subtypes: None, + fields: Some( + vec![( + "f1".to_string(), + FieldInfoJSON { + multiple: false, + required: true, + types: vec![NodeTypeJSON { + kind: "_v2".to_string(), + named: true, + }] + } + ),] + .into_iter() + .collect() + ) + } + ); + } + + 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(); + generate_node_types_json( + &syntax_grammar, + &lexical_grammar, + &simple_aliases, + &variable_info, + ) + } +}