From f104458d45e30024f8a4a02c1ad4101ed74b08f9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Aug 2018 20:50:37 +0300 Subject: parameter parsing does not destroy blocks --- crates/libsyntax2/src/grammar/expressions/atom.rs | 2 +- crates/libsyntax2/src/grammar/expressions/mod.rs | 2 +- crates/libsyntax2/src/grammar/items/mod.rs | 4 +++- crates/libsyntax2/src/grammar/params.rs | 11 ++++++++++ crates/libsyntax2/src/grammar/paths.rs | 3 +++ crates/libsyntax2/src/grammar/patterns.rs | 7 +++++++ crates/libsyntax2/src/grammar/types.rs | 8 ++++++++ crates/libsyntax2/src/lib.rs | 11 +++++++++- .../tests/data/parser/err/0015_curly_in_params.rs | 2 ++ .../tests/data/parser/err/0015_curly_in_params.txt | 24 ++++++++++++++++++++++ 10 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.rs create mode 100644 crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.txt (limited to 'crates') diff --git a/crates/libsyntax2/src/grammar/expressions/atom.rs b/crates/libsyntax2/src/grammar/expressions/atom.rs index 417366026..b0e270426 100644 --- a/crates/libsyntax2/src/grammar/expressions/atom.rs +++ b/crates/libsyntax2/src/grammar/expressions/atom.rs @@ -13,7 +13,7 @@ use super::*; // let _ = b"e"; // let _ = br"f"; // } -const LITERAL_FIRST: TokenSet = +pub(crate) const LITERAL_FIRST: TokenSet = token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR, STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING]; diff --git a/crates/libsyntax2/src/grammar/expressions/mod.rs b/crates/libsyntax2/src/grammar/expressions/mod.rs index e133c1d9b..59a0564d9 100644 --- a/crates/libsyntax2/src/grammar/expressions/mod.rs +++ b/crates/libsyntax2/src/grammar/expressions/mod.rs @@ -1,7 +1,7 @@ mod atom; use super::*; -pub(super) use self::atom::literal; +pub(super) use self::atom::{literal, LITERAL_FIRST}; const EXPR_FIRST: TokenSet = LHS_FIRST; diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index d236fb506..206c85280 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs @@ -250,8 +250,10 @@ fn function(p: &mut Parser, flavor: ItemFlavor) { // test fn_decl // trait T { fn foo(); } - if !p.eat(SEMI) { + if p.at(L_CURLY) { expressions::block(p); + } else { + p.expect(SEMI); } } diff --git a/crates/libsyntax2/src/grammar/params.rs b/crates/libsyntax2/src/grammar/params.rs index 5b1322b3a..bc0cb44ba 100644 --- a/crates/libsyntax2/src/grammar/params.rs +++ b/crates/libsyntax2/src/grammar/params.rs @@ -48,6 +48,10 @@ fn list_(p: &mut Parser, flavor: Flavor) { opt_self_param(p); } while !p.at(EOF) && !p.at(ket) { + if !VALUE_PARAMETER_FIRST.contains(p.current()) { + p.error("expected value parameter"); + break; + } value_parameter(p, flavor); if !p.at(ket) { p.expect(COMMA); @@ -57,6 +61,13 @@ fn list_(p: &mut Parser, flavor: Flavor) { m.complete(p, PARAM_LIST); } + +const VALUE_PARAMETER_FIRST: TokenSet = + token_set_union![ + patterns::PATTERN_FIRST, + types::TYPE_FIRST, + ]; + fn value_parameter(p: &mut Parser, flavor: Flavor) { let m = p.start(); match flavor { diff --git a/crates/libsyntax2/src/grammar/paths.rs b/crates/libsyntax2/src/grammar/paths.rs index 8f5e82d91..7c9fb8be2 100644 --- a/crates/libsyntax2/src/grammar/paths.rs +++ b/crates/libsyntax2/src/grammar/paths.rs @@ -1,5 +1,8 @@ use super::*; +pub(super) const PATH_FIRST: TokenSet = + token_set![IDENT, SELF_KW, SUPER_KW, COLONCOLON, L_ANGLE]; + pub(super) fn is_path_start(p: &Parser) -> bool { match p.current() { IDENT | SELF_KW | SUPER_KW | COLONCOLON => true, diff --git a/crates/libsyntax2/src/grammar/patterns.rs b/crates/libsyntax2/src/grammar/patterns.rs index 7ddbfa318..11852e0d3 100644 --- a/crates/libsyntax2/src/grammar/patterns.rs +++ b/crates/libsyntax2/src/grammar/patterns.rs @@ -1,5 +1,12 @@ use super::*; +pub(super) const PATTERN_FIRST: TokenSet = + token_set_union![ + token_set![REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP], + expressions::LITERAL_FIRST, + paths::PATH_FIRST, + ]; + pub(super) fn pattern(p: &mut Parser) { if let Some(lhs) = atom_pat(p) { // test range_pat diff --git a/crates/libsyntax2/src/grammar/types.rs b/crates/libsyntax2/src/grammar/types.rs index 2088a38e3..89030e66c 100644 --- a/crates/libsyntax2/src/grammar/types.rs +++ b/crates/libsyntax2/src/grammar/types.rs @@ -1,5 +1,13 @@ use super::*; +pub(super) const TYPE_FIRST: TokenSet = + token_set_union![ + token_set![ + L_PAREN, EXCL, STAR, L_BRACK, AMP, UNDERSCORE, FN_KW, UNSAFE_KW, EXTERN_KW, FOR_KW, IMPL_KW, DYN_KW, L_ANGLE, + ], + paths::PATH_FIRST, + ]; + pub(super) fn type_(p: &mut Parser) { match p.current() { L_PAREN => paren_or_tuple_type(p), diff --git a/crates/libsyntax2/src/lib.rs b/crates/libsyntax2/src/lib.rs index d3ecbe470..9f9f3ab3a 100644 --- a/crates/libsyntax2/src/lib.rs +++ b/crates/libsyntax2/src/lib.rs @@ -58,6 +58,10 @@ pub fn parse(text: &str) -> SyntaxNode { res } +#[cfg(not(debug_assertions))] +fn validate_block_structure(_: SyntaxNodeRef) {} + +#[cfg(debug_assertions)] fn validate_block_structure(root: SyntaxNodeRef) { let mut stack = Vec::new(); for node in algo::walk::preorder(root) { @@ -67,7 +71,12 @@ fn validate_block_structure(root: SyntaxNodeRef) { } SyntaxKind::R_CURLY => { if let Some(pair) = stack.pop() { - assert_eq!(node.parent(), pair.parent()); + assert_eq!( + node.parent(), + pair.parent(), + "unpaired curleys:\n{}", + utils::dump_tree(root), + ); assert!( node.next_sibling().is_none() && pair.prev_sibling().is_none(), "floating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", diff --git a/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.rs b/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.rs new file mode 100644 index 000000000..156e70251 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.rs @@ -0,0 +1,2 @@ +fn foo(}) { +} diff --git a/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.txt b/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.txt new file mode 100644 index 000000000..841379797 --- /dev/null +++ b/crates/libsyntax2/tests/data/parser/err/0015_curly_in_params.txt @@ -0,0 +1,24 @@ +FILE@[0; 14) + FN_DEF@[0; 7) + FN_KW@[0; 2) + WHITESPACE@[2; 3) + NAME@[3; 6) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 7) + L_PAREN@[6; 7) + err: `expected value parameter` + err: `expected R_PAREN` + err: `expected SEMI` + err: `expected an item` + ERROR@[7; 8) + R_CURLY@[7; 8) + err: `expected an item` + ERROR@[8; 9) + R_PAREN@[8; 9) + WHITESPACE@[9; 10) + err: `expected an item` + ERROR@[10; 13) + L_CURLY@[10; 11) + WHITESPACE@[11; 12) + R_CURLY@[12; 13) + WHITESPACE@[13; 14) -- cgit v1.2.3