From cc081b7e1c68360ec157a31fa7fa32a38345e8d6 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 17 Nov 2020 15:34:41 +0100 Subject: syntax,ssr: Implement statement parsing --- crates/ssr/src/parsing.rs | 1 + crates/syntax/src/lib.rs | 7 +++ crates/syntax/src/tests.rs | 9 +++ .../parser/fragments/stmt/err/0000_attr.rast | 1 + .../parser/fragments/stmt/err/0000_attr.rs | 1 + .../parser/fragments/stmt/err/0000_fn_call.rast | 1 + .../parser/fragments/stmt/err/0000_fn_call.rs | 1 + .../parser/fragments/stmt/err/0000_let_stmt.rast | 1 + .../parser/fragments/stmt/err/0000_let_stmt.rs | 1 + .../fragments/stmt/err/0000_macro_let_stmt.rast | 1 + .../fragments/stmt/err/0000_macro_let_stmt.rs | 1 + .../stmt/err/0000_macro_unterminated_let_stmt.rast | 1 + .../stmt/err/0000_macro_unterminated_let_stmt.rs | 1 + .../fragments/stmt/err/0000_multiple_stmts.rast | 1 + .../fragments/stmt/err/0000_multiple_stmts.rs | 1 + .../fragments/stmt/err/0000_open_parenthesis.rast | 1 + .../fragments/stmt/err/0000_open_parenthesis.rs | 1 + .../parser/fragments/stmt/err/0000_semicolon.rast | 1 + .../parser/fragments/stmt/err/0000_semicolon.rs | 1 + .../fragments/stmt/err/0000_unterminated_expr.rast | 1 + .../fragments/stmt/err/0000_unterminated_expr.rs | 1 + .../parser/fragments/stmt/ok/0000_expr.rast | 9 +++ .../parser/fragments/stmt/ok/0000_expr.rs | 1 + .../parser/fragments/stmt/ok/0000_expr_block.rast | 69 ++++++++++++++++++++++ .../parser/fragments/stmt/ok/0000_expr_block.rs | 5 ++ .../parser/fragments/stmt/ok/0000_struct_item.rast | 22 +++++++ .../parser/fragments/stmt/ok/0000_struct_item.rs | 3 + .../stmt/ok/0000_unterminated_fn_call.rast | 10 ++++ .../fragments/stmt/ok/0000_unterminated_fn_call.rs | 1 + .../stmt/ok/0000_unterminated_let_stmt.rast | 11 ++++ .../stmt/ok/0000_unterminated_let_stmt.rs | 1 + 31 files changed, 167 insertions(+) create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_fn_call.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_fn_call.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_let_stmt.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_let_stmt.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_let_stmt.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_let_stmt.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_unterminated_let_stmt.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_unterminated_let_stmt.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rs create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rast create mode 100644 crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rs diff --git a/crates/ssr/src/parsing.rs b/crates/ssr/src/parsing.rs index f3b084baf..289affe90 100644 --- a/crates/ssr/src/parsing.rs +++ b/crates/ssr/src/parsing.rs @@ -78,6 +78,7 @@ impl ParsedRule { builder.try_add(ast::Item::parse(&raw_pattern), raw_template.map(ast::Item::parse)); builder.try_add(ast::Path::parse(&raw_pattern), raw_template.map(ast::Path::parse)); builder.try_add(ast::Pat::parse(&raw_pattern), raw_template.map(ast::Pat::parse)); + builder.try_add(ast::Stmt::parse(&raw_pattern), raw_template.map(ast::Stmt::parse)); builder.build() } } diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index 4d272f367..51ae3da07 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs @@ -212,6 +212,13 @@ impl ast::Attr { } } +impl ast::Stmt { + /// Returns `text`, parsed as statement, but only if it has no errors. + pub fn parse(text: &str) -> Result { + parsing::parse_text_fragment(text, parser::FragmentKind::Statement) + } +} + /// Matches a `SyntaxNode` against an `ast` type. /// /// # Example: diff --git a/crates/syntax/src/tests.rs b/crates/syntax/src/tests.rs index 8c217dfe0..9d3433c9d 100644 --- a/crates/syntax/src/tests.rs +++ b/crates/syntax/src/tests.rs @@ -102,6 +102,15 @@ fn type_parser_tests() { ); } +#[test] +fn stmt_parser_tests() { + fragment_parser_dir_test( + &["parser/fragments/stmt/ok"], + &["parser/fragments/stmt/err"], + crate::ast::Stmt::parse, + ); +} + #[test] fn parser_fuzz_tests() { for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) { diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rast @@ -0,0 +1 @@ +ERROR diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rs new file mode 100644 index 000000000..988df0705 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rs @@ -0,0 +1 @@ +#[foo] diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_fn_call.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_fn_call.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_fn_call.rast @@ -0,0 +1 @@ +ERROR diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_fn_call.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_fn_call.rs new file mode 100644 index 000000000..a280f9a5c --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_fn_call.rs @@ -0,0 +1 @@ +foo(); diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_let_stmt.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_let_stmt.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_let_stmt.rast @@ -0,0 +1 @@ +ERROR diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_let_stmt.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_let_stmt.rs new file mode 100644 index 000000000..de8a7f1fc --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_let_stmt.rs @@ -0,0 +1 @@ +let x = 10; diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_let_stmt.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_let_stmt.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_let_stmt.rast @@ -0,0 +1 @@ +ERROR diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_let_stmt.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_let_stmt.rs new file mode 100644 index 000000000..075f30159 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_let_stmt.rs @@ -0,0 +1 @@ +m1!{ let a = 0; }; diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_unterminated_let_stmt.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_unterminated_let_stmt.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_unterminated_let_stmt.rast @@ -0,0 +1 @@ +ERROR diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_unterminated_let_stmt.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_unterminated_let_stmt.rs new file mode 100644 index 000000000..075f30159 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_macro_unterminated_let_stmt.rs @@ -0,0 +1 @@ +m1!{ let a = 0; }; diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rast @@ -0,0 +1 @@ +ERROR diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rs new file mode 100644 index 000000000..7e3b2fd49 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rs @@ -0,0 +1 @@ +a(); b(); c() diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rast @@ -0,0 +1 @@ +ERROR diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rs new file mode 100644 index 000000000..2d06f3766 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rs @@ -0,0 +1 @@ +( diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rast @@ -0,0 +1 @@ +ERROR diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rs new file mode 100644 index 000000000..092bc2b04 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rs @@ -0,0 +1 @@ +; diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rast @@ -0,0 +1 @@ +ERROR diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rs new file mode 100644 index 000000000..ca49acb07 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rs @@ -0,0 +1 @@ +1 + diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rast new file mode 100644 index 000000000..274fdf16d --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rast @@ -0,0 +1,9 @@ +EXPR_STMT@0..5 + BIN_EXPR@0..5 + LITERAL@0..1 + INT_NUMBER@0..1 "1" + WHITESPACE@1..2 " " + PLUS@2..3 "+" + WHITESPACE@3..4 " " + LITERAL@4..5 + INT_NUMBER@4..5 "1" diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rs new file mode 100644 index 000000000..8d2f0971e --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rs @@ -0,0 +1 @@ +1 + 1 diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rast new file mode 100644 index 000000000..6c946091f --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rast @@ -0,0 +1,69 @@ +EXPR_STMT@0..55 + BLOCK_EXPR@0..55 + L_CURLY@0..1 "{" + WHITESPACE@1..6 "\n " + LET_STMT@6..20 + LET_KW@6..9 "let" + WHITESPACE@9..10 " " + IDENT_PAT@10..11 + NAME@10..11 + IDENT@10..11 "x" + WHITESPACE@11..12 " " + EQ@12..13 "=" + WHITESPACE@13..14 " " + CALL_EXPR@14..19 + PATH_EXPR@14..17 + PATH@14..17 + PATH_SEGMENT@14..17 + NAME_REF@14..17 + IDENT@14..17 "foo" + ARG_LIST@17..19 + L_PAREN@17..18 "(" + R_PAREN@18..19 ")" + SEMICOLON@19..20 ";" + WHITESPACE@20..25 "\n " + LET_STMT@25..39 + LET_KW@25..28 "let" + WHITESPACE@28..29 " " + IDENT_PAT@29..30 + NAME@29..30 + IDENT@29..30 "y" + WHITESPACE@30..31 " " + EQ@31..32 "=" + WHITESPACE@32..33 " " + CALL_EXPR@33..38 + PATH_EXPR@33..36 + PATH@33..36 + PATH_SEGMENT@33..36 + NAME_REF@33..36 + IDENT@33..36 "bar" + ARG_LIST@36..38 + L_PAREN@36..37 "(" + R_PAREN@37..38 ")" + SEMICOLON@38..39 ";" + WHITESPACE@39..44 "\n " + CALL_EXPR@44..53 + PATH_EXPR@44..46 + PATH@44..46 + PATH_SEGMENT@44..46 + NAME_REF@44..46 + IDENT@44..46 "Ok" + ARG_LIST@46..53 + L_PAREN@46..47 "(" + BIN_EXPR@47..52 + PATH_EXPR@47..48 + PATH@47..48 + PATH_SEGMENT@47..48 + NAME_REF@47..48 + IDENT@47..48 "x" + WHITESPACE@48..49 " " + PLUS@49..50 "+" + WHITESPACE@50..51 " " + PATH_EXPR@51..52 + PATH@51..52 + PATH_SEGMENT@51..52 + NAME_REF@51..52 + IDENT@51..52 "y" + R_PAREN@52..53 ")" + WHITESPACE@53..54 "\n" + R_CURLY@54..55 "}" diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rs new file mode 100644 index 000000000..ffa5c1e66 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rs @@ -0,0 +1,5 @@ +{ + let x = foo(); + let y = bar(); + Ok(x + y) +} diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rast new file mode 100644 index 000000000..64c5d2969 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rast @@ -0,0 +1,22 @@ +STRUCT@0..28 + STRUCT_KW@0..6 "struct" + WHITESPACE@6..7 " " + NAME@7..10 + IDENT@7..10 "Foo" + WHITESPACE@10..11 " " + RECORD_FIELD_LIST@11..28 + L_CURLY@11..12 "{" + WHITESPACE@12..17 "\n " + RECORD_FIELD@17..25 + NAME@17..20 + IDENT@17..20 "bar" + COLON@20..21 ":" + WHITESPACE@21..22 " " + PATH_TYPE@22..25 + PATH@22..25 + PATH_SEGMENT@22..25 + NAME_REF@22..25 + IDENT@22..25 "u32" + COMMA@25..26 "," + WHITESPACE@26..27 "\n" + R_CURLY@27..28 "}" diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rs new file mode 100644 index 000000000..e5473e3ac --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rs @@ -0,0 +1,3 @@ +struct Foo { + bar: u32, +} diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rast new file mode 100644 index 000000000..9089906bc --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rast @@ -0,0 +1,10 @@ +EXPR_STMT@0..5 + CALL_EXPR@0..5 + PATH_EXPR@0..3 + PATH@0..3 + PATH_SEGMENT@0..3 + NAME_REF@0..3 + IDENT@0..3 "foo" + ARG_LIST@3..5 + L_PAREN@3..4 "(" + R_PAREN@4..5 ")" diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rs new file mode 100644 index 000000000..eb28ef440 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rs @@ -0,0 +1 @@ +foo() diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rast new file mode 100644 index 000000000..37663671f --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rast @@ -0,0 +1,11 @@ +LET_STMT@0..10 + LET_KW@0..3 "let" + WHITESPACE@3..4 " " + IDENT_PAT@4..5 + NAME@4..5 + IDENT@4..5 "x" + WHITESPACE@5..6 " " + EQ@6..7 "=" + WHITESPACE@7..8 " " + LITERAL@8..10 + INT_NUMBER@8..10 "10" diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rs new file mode 100644 index 000000000..78364b2a9 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rs @@ -0,0 +1 @@ +let x = 10 -- cgit v1.2.3