diff --git a/cli/src/generate/prepare_grammar/intern_symbols.rs b/cli/src/generate/prepare_grammar/intern_symbols.rs index dd48c890..567c61ac 100644 --- a/cli/src/generate/prepare_grammar/intern_symbols.rs +++ b/cli/src/generate/prepare_grammar/intern_symbols.rs @@ -102,9 +102,7 @@ impl<'a> Interner<'a> { fn intern_rule(&self, rule: &Rule, name: Option<&str>) -> Result { match rule { Rule::Choice(elements) => { - if let Some(result) = self.intern_single(elements, name) { - return result; - } + self.check_single(elements, name); let mut result = Vec::with_capacity(elements.len()); for element in elements { result.push(self.intern_rule(element, name)?); @@ -112,9 +110,7 @@ impl<'a> Interner<'a> { Ok(Rule::Choice(result)) } Rule::Seq(elements) => { - if let Some(result) = self.intern_single(elements, name) { - return result; - } + self.check_single(elements, name); let mut result = Vec::with_capacity(elements.len()); for element in elements { result.push(self.intern_rule(element, name)?); @@ -153,17 +149,13 @@ impl<'a> Interner<'a> { } // In the case of a seq or choice rule of 1 element in a hidden rule, weird - // inconsistent behavior w/ queries can occur. So we should treat it as that single rule itself - // in this case. - fn intern_single(&self, elements: &[Rule], name: Option<&str>) -> Option> { + // inconsistent behavior with queries can occur. So we should warn the user about it. + fn check_single(&self, elements: &[Rule], name: Option<&str>) { if elements.len() == 1 && matches!(elements[0], Rule::String(_) | Rule::Pattern(_, _)) { eprintln!( "Warning: rule {} is just a `seq` or `choice` rule with a single element. This is unnecessary.", name.unwrap_or_default() ); - Some(self.intern_rule(&elements[0], name)) - } else { - None } } } @@ -258,42 +250,6 @@ mod tests { } } - #[test] - fn test_interning_a_seq_or_choice_of_one_rule() { - let grammar = intern_symbols(&build_grammar(vec![ - Variable::named("w", Rule::choice(vec![Rule::string("a")])), - Variable::named("x", Rule::seq(vec![Rule::pattern("b", "")])), - Variable::named("y", Rule::string("a")), - Variable::named("z", Rule::pattern("b", "")), - // Hidden rules should not affect this. - Variable::hidden("_a", Rule::choice(vec![Rule::string("a")])), - Variable::hidden("_b", Rule::seq(vec![Rule::pattern("b", "")])), - Variable::hidden("_c", Rule::string("a")), - Variable::hidden("_d", Rule::pattern("b", "")), - ])) - .unwrap(); - - assert_eq!( - grammar.variables, - vec![ - Variable::named("w", Rule::string("a")), - Variable::named("x", Rule::pattern("b", "")), - Variable::named("y", Rule::string("a")), - Variable::named("z", Rule::pattern("b", "")), - // Hidden rules show no change. - Variable::hidden("_a", Rule::string("a")), - Variable::hidden("_b", Rule::pattern("b", "")), - Variable::hidden("_c", Rule::string("a")), - Variable::hidden("_d", Rule::pattern("b", "")), - ] - ); - - assert_eq!(grammar.variables[0].rule, grammar.variables[2].rule); - assert_eq!(grammar.variables[1].rule, grammar.variables[3].rule); - assert_eq!(grammar.variables[4].rule, grammar.variables[6].rule); - assert_eq!(grammar.variables[5].rule, grammar.variables[7].rule); - } - fn build_grammar(variables: Vec) -> InputGrammar { InputGrammar { variables, diff --git a/cli/src/tests/query_test.rs b/cli/src/tests/query_test.rs index d188921b..f37821c1 100644 --- a/cli/src/tests/query_test.rs +++ b/cli/src/tests/query_test.rs @@ -5017,7 +5017,7 @@ fn test_grammar_with_aliased_literal_query() { let (parser_name, parser_code) = generate_parser_for_grammar( r#" { - "name": "test_grammar_with_aliased_literal_query", + "name": "test", "rules": { "source": { "type": "REPEAT", @@ -5077,72 +5077,10 @@ fn test_grammar_with_aliased_literal_query() { &language, r#" (compound_statement "}" @bracket1) - (expansion) @bracket2 - "#, - ); - - assert!(query.is_ok()); - - let query = Query::new( - &language, - r#" (expansion "}" @bracket2) "#, ); - assert!(query.is_err()); -} - -#[test] -fn test_query_with_seq_or_choice_of_one_rule() { - // module.exports = grammar({ - // name: 'test', - // - // rules: { - // source: $ => choice($._seq, $._choice), - // - // _seq: $ => seq("hi"), - // _choice: $ => choice("bye"), - // }, - // }); - - let (parser_name, parser_code) = generate_parser_for_grammar( - r#" - { - "name": "test_query_with_seq_or_choice_of_one_rule", - "rules": { - "source": { - "type": "CHOICE", - "members": [ - { "type": "SYMBOL", "name": "_seq" }, - { "type": "SYMBOL", "name": "_choice" } - ] - }, - "_seq": { - "type": "SEQ", - "members": [{ "type": "STRING", "value": "hi" }] - }, - "_choice": { - "type": "CHOICE", - "members": [ { "type": "STRING", "value": "bye" } ] - } - }, - "extras": [{ "type": "PATTERN", "value": "\\s" }] - } - "#, - ) - .unwrap(); - - let language = get_test_language(&parser_name, &parser_code, None); - - let query = Query::new( - &language, - r#" - "hi" @seq - "bye" @choice - "#, - ); - assert!(query.is_ok()); }