From 2ef16a4121ad497e7fb290445ffe644b6b8ceae6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 10 Feb 2018 12:35:40 +0300 Subject: [PATCH 1/2] G: type item --- grammar.ron | 2 + src/parser/grammar/items/mod.rs | 80 ++++++++++++------- src/parser/grammar/type_params.rs | 3 + src/parser/grammar/types.rs | 11 ++- src/syntax_kinds.rs | 5 ++ tests/data/lexer/0011_keywords.rs | 2 +- tests/data/lexer/0011_keywords.txt | 2 + .../inline/0014_type_item_type_params.rs | 1 + .../inline/0014_type_item_type_params.txt | 17 ++++ tests/data/parser/inline/0015_type_item.rs | 1 + tests/data/parser/inline/0015_type_item.txt | 11 +++ .../inline/0016_type_item_where_clause.rs | 1 + .../inline/0016_type_item_where_clause.txt | 19 +++++ tests/testutils/src/lib.rs | 7 +- 14 files changed, 128 insertions(+), 34 deletions(-) create mode 100644 tests/data/parser/inline/0014_type_item_type_params.rs create mode 100644 tests/data/parser/inline/0014_type_item_type_params.txt create mode 100644 tests/data/parser/inline/0015_type_item.rs create mode 100644 tests/data/parser/inline/0015_type_item.txt create mode 100644 tests/data/parser/inline/0016_type_item_where_clause.rs create mode 100644 tests/data/parser/inline/0016_type_item_where_clause.txt diff --git a/grammar.ron b/grammar.ron index e97ef0c2ca..8e265323b4 100644 --- a/grammar.ron +++ b/grammar.ron @@ -26,6 +26,7 @@ Grammar( "static", "mut", "unsafe", + "type", ], contextual_keywords: [ "auto", @@ -98,6 +99,7 @@ Grammar( "CONST_ITEM", "TRAIT_ITEM", "IMPL_ITEM", + "TYPE_ITEM", "EXTERN_BLOCK", "ENUM_VARIANT", diff --git a/src/parser/grammar/items/mod.rs b/src/parser/grammar/items/mod.rs index b73628ec0c..ffe86fa976 100644 --- a/src/parser/grammar/items/mod.rs +++ b/src/parser/grammar/items/mod.rs @@ -150,7 +150,14 @@ fn item(p: &mut Parser) { } } } - + FN_KW => { + fn_item(p); + FN_ITEM + } + TYPE_KW => { + type_item(p); + TYPE_ITEM + } MOD_KW => { mod_item(p); MOD_ITEM @@ -163,10 +170,6 @@ fn item(p: &mut Parser) { structs::enum_item(p); ENUM_ITEM } - FN_KW => { - fn_item(p); - FN_ITEM - } L_CURLY => { item.abandon(p); error_block(p, "expected item"); @@ -203,29 +206,6 @@ fn extern_block(p: &mut Parser) { p.expect(R_CURLY); } -fn mod_item(p: &mut Parser) { - assert!(p.at(MOD_KW)); - p.bump(); - - if p.expect(IDENT) && !p.eat(SEMI) { - if p.expect(L_CURLY) { - mod_contents(p, true); - p.expect(R_CURLY); - } - } -} - -fn abi(p: &mut Parser) { - assert!(p.at(EXTERN_KW)); - let abi = p.start(); - p.bump(); - match p.current() { - STRING | RAW_STRING => p.bump(), - _ => (), - } - abi.complete(p, ABI); -} - fn fn_item(p: &mut Parser) { assert!(p.at(FN_KW)); p.bump(); @@ -248,3 +228,47 @@ fn fn_item(p: &mut Parser) { p.expect(R_PAREN); } } + +// test type_item +// type Foo = Bar; +fn type_item(p: &mut Parser) { + assert!(p.at(TYPE_KW)); + p.bump(); + + p.expect(IDENT); + + // test type_item_type_params + // type Result = (); + type_params::list(p); + + // test type_item_where_clause + // type Foo where Foo: Copy = (); + type_params::where_clause(p); + + p.expect(EQ); + types::type_ref(p); + p.expect(SEMI); +} + +fn mod_item(p: &mut Parser) { + assert!(p.at(MOD_KW)); + p.bump(); + + if p.expect(IDENT) && !p.eat(SEMI) { + if p.expect(L_CURLY) { + mod_contents(p, true); + p.expect(R_CURLY); + } + } +} + +fn abi(p: &mut Parser) { + assert!(p.at(EXTERN_KW)); + let abi = p.start(); + p.bump(); + match p.current() { + STRING | RAW_STRING => p.bump(), + _ => (), + } + abi.complete(p, ABI); +} diff --git a/src/parser/grammar/type_params.rs b/src/parser/grammar/type_params.rs index 12c9a53627..73c3cf8b8c 100644 --- a/src/parser/grammar/type_params.rs +++ b/src/parser/grammar/type_params.rs @@ -71,5 +71,8 @@ pub(super) fn list(p: &mut Parser) { pub(super) fn where_clause(p: &mut Parser) { if p.at(WHERE_KW) { p.bump(); + p.expect(IDENT); + p.expect(COLON); + p.expect(IDENT); } } diff --git a/src/parser/grammar/types.rs b/src/parser/grammar/types.rs index 1a3d44a0ab..c798edd08a 100644 --- a/src/parser/grammar/types.rs +++ b/src/parser/grammar/types.rs @@ -1,5 +1,14 @@ use super::*; pub(super) fn type_ref(p: &mut Parser) { - p.expect(IDENT); + match p.current() { + IDENT => p.bump(), + L_PAREN => { + p.bump(); + p.expect(R_PAREN); + } + _ => { + p.error("expected type"); + } + } } diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index 27bc1cafa5..501b940bbe 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -83,6 +83,7 @@ pub enum SyntaxKind { STATIC_KW, MUT_KW, UNSAFE_KW, + TYPE_KW, AUTO_KW, DEFAULT_KW, UNION_KW, @@ -97,6 +98,7 @@ pub enum SyntaxKind { CONST_ITEM, TRAIT_ITEM, IMPL_ITEM, + TYPE_ITEM, EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, @@ -203,6 +205,7 @@ impl SyntaxKind { STATIC_KW => &SyntaxInfo { name: "STATIC_KW" }, MUT_KW => &SyntaxInfo { name: "MUT_KW" }, UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" }, + TYPE_KW => &SyntaxInfo { name: "TYPE_KW" }, AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, UNION_KW => &SyntaxInfo { name: "UNION_KW" }, @@ -217,6 +220,7 @@ impl SyntaxKind { CONST_ITEM => &SyntaxInfo { name: "CONST_ITEM" }, TRAIT_ITEM => &SyntaxInfo { name: "TRAIT_ITEM" }, IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, + TYPE_ITEM => &SyntaxInfo { name: "TYPE_ITEM" }, EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, @@ -268,6 +272,7 @@ pub(crate) fn ident_to_keyword(ident: &str) -> Option { "static" => Some(STATIC_KW), "mut" => Some(MUT_KW), "unsafe" => Some(UNSAFE_KW), + "type" => Some(TYPE_KW), _ => None, } } diff --git a/tests/data/lexer/0011_keywords.rs b/tests/data/lexer/0011_keywords.rs index b74fc606ec..7a9509f3cd 100644 --- a/tests/data/lexer/0011_keywords.rs +++ b/tests/data/lexer/0011_keywords.rs @@ -1,3 +1,3 @@ fn use struct trait enum impl true false as extern crate mod pub self super in where for loop while if match const -static mut +static mut type diff --git a/tests/data/lexer/0011_keywords.txt b/tests/data/lexer/0011_keywords.txt index 05b1f09954..96528952b0 100644 --- a/tests/data/lexer/0011_keywords.txt +++ b/tests/data/lexer/0011_keywords.txt @@ -47,4 +47,6 @@ WHITESPACE 1 "\n" STATIC_KW 6 "static" WHITESPACE 1 " " MUT_KW 3 "mut" +WHITESPACE 1 " " +TYPE_KW 4 "type" WHITESPACE 1 "\n" diff --git a/tests/data/parser/inline/0014_type_item_type_params.rs b/tests/data/parser/inline/0014_type_item_type_params.rs new file mode 100644 index 0000000000..defd110c49 --- /dev/null +++ b/tests/data/parser/inline/0014_type_item_type_params.rs @@ -0,0 +1 @@ +type Result = (); diff --git a/tests/data/parser/inline/0014_type_item_type_params.txt b/tests/data/parser/inline/0014_type_item_type_params.txt new file mode 100644 index 0000000000..b0f0f83375 --- /dev/null +++ b/tests/data/parser/inline/0014_type_item_type_params.txt @@ -0,0 +1,17 @@ +FILE@[0; 21) + TYPE_ITEM@[0; 21) + TYPE_KW@[0; 4) + WHITESPACE@[4; 5) + IDENT@[5; 11) "Result" + TYPE_PARAM_LIST@[11; 15) + L_ANGLE@[11; 12) + TYPE_PARAM@[12; 13) + IDENT@[12; 13) "T" + R_ANGLE@[13; 14) + WHITESPACE@[14; 15) + EQ@[15; 16) + WHITESPACE@[16; 17) + L_PAREN@[17; 18) + R_PAREN@[18; 19) + SEMI@[19; 20) + WHITESPACE@[20; 21) diff --git a/tests/data/parser/inline/0015_type_item.rs b/tests/data/parser/inline/0015_type_item.rs new file mode 100644 index 0000000000..04c0344fa3 --- /dev/null +++ b/tests/data/parser/inline/0015_type_item.rs @@ -0,0 +1 @@ +type Foo = Bar; diff --git a/tests/data/parser/inline/0015_type_item.txt b/tests/data/parser/inline/0015_type_item.txt new file mode 100644 index 0000000000..382d7ece0c --- /dev/null +++ b/tests/data/parser/inline/0015_type_item.txt @@ -0,0 +1,11 @@ +FILE@[0; 16) + TYPE_ITEM@[0; 16) + TYPE_KW@[0; 4) + WHITESPACE@[4; 5) + IDENT@[5; 8) "Foo" + WHITESPACE@[8; 9) + EQ@[9; 10) + WHITESPACE@[10; 11) + IDENT@[11; 14) "Bar" + SEMI@[14; 15) + WHITESPACE@[15; 16) diff --git a/tests/data/parser/inline/0016_type_item_where_clause.rs b/tests/data/parser/inline/0016_type_item_where_clause.rs new file mode 100644 index 0000000000..a602d07f03 --- /dev/null +++ b/tests/data/parser/inline/0016_type_item_where_clause.rs @@ -0,0 +1 @@ +type Foo where Foo: Copy = (); diff --git a/tests/data/parser/inline/0016_type_item_where_clause.txt b/tests/data/parser/inline/0016_type_item_where_clause.txt new file mode 100644 index 0000000000..28fcc7c0a3 --- /dev/null +++ b/tests/data/parser/inline/0016_type_item_where_clause.txt @@ -0,0 +1,19 @@ +FILE@[0; 31) + TYPE_ITEM@[0; 31) + TYPE_KW@[0; 4) + WHITESPACE@[4; 5) + IDENT@[5; 8) "Foo" + WHITESPACE@[8; 9) + WHERE_KW@[9; 14) + WHITESPACE@[14; 15) + IDENT@[15; 18) "Foo" + COLON@[18; 19) + WHITESPACE@[19; 20) + IDENT@[20; 24) "Copy" + WHITESPACE@[24; 25) + EQ@[25; 26) + WHITESPACE@[26; 27) + L_PAREN@[27; 28) + R_PAREN@[28; 29) + SEMI@[29; 30) + WHITESPACE@[30; 31) diff --git a/tests/testutils/src/lib.rs b/tests/testutils/src/lib.rs index f829b243b4..d181e455b1 100644 --- a/tests/testutils/src/lib.rs +++ b/tests/testutils/src/lib.rs @@ -76,15 +76,14 @@ fn test_from_dir(dir: &Path) -> Vec { fn print_difference(expected: &str, actual: &str, path: &Path) { let dir = project_dir(); let path = path.strip_prefix(&dir).unwrap_or_else(|_| path); - println!("\nfile: {}", path.display()); if expected.trim() == actual.trim() { - println!("whitespace difference"); - println!("rewriting the file"); + println!("whitespace difference, rewriting"); file::put_text(path, actual).unwrap(); } else { let changeset = Changeset::new(actual, expected, "\n"); - println!("{}", changeset); + print!("{}", changeset); } + println!("file: {}\n", path.display()); panic!("Comparison failed") } From dd6e5371ebddeaeecb3d1e2d3d6c8b3c9050bb05 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 10 Feb 2018 12:53:07 +0300 Subject: [PATCH 2/2] G: where clause --- grammar.ron | 1 + src/parser/grammar/type_params.rs | 2 ++ src/syntax_kinds.rs | 2 ++ .../inline/0016_type_item_where_clause.txt | 17 +++++++++-------- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/grammar.ron b/grammar.ron index 8e265323b4..c38bf654d5 100644 --- a/grammar.ron +++ b/grammar.ron @@ -114,6 +114,7 @@ Grammar( "ALIAS", "VISIBILITY", "TYPE_PARAM_LIST", + "WHERE_CLAUSE", "LIFETIME_PARAM", "TYPE_PARAM", "ABI", diff --git a/src/parser/grammar/type_params.rs b/src/parser/grammar/type_params.rs index 73c3cf8b8c..8f62a471cc 100644 --- a/src/parser/grammar/type_params.rs +++ b/src/parser/grammar/type_params.rs @@ -70,9 +70,11 @@ pub(super) fn list(p: &mut Parser) { pub(super) fn where_clause(p: &mut Parser) { if p.at(WHERE_KW) { + let m = p.start(); p.bump(); p.expect(IDENT); p.expect(COLON); p.expect(IDENT); + m.complete(p, WHERE_CLAUSE); } } diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index 501b940bbe..dc287f0f40 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -112,6 +112,7 @@ pub enum SyntaxKind { ALIAS, VISIBILITY, TYPE_PARAM_LIST, + WHERE_CLAUSE, LIFETIME_PARAM, TYPE_PARAM, ABI, @@ -234,6 +235,7 @@ impl SyntaxKind { ALIAS => &SyntaxInfo { name: "ALIAS" }, VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, + WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" }, TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" }, ABI => &SyntaxInfo { name: "ABI" }, diff --git a/tests/data/parser/inline/0016_type_item_where_clause.txt b/tests/data/parser/inline/0016_type_item_where_clause.txt index 28fcc7c0a3..ddd3358706 100644 --- a/tests/data/parser/inline/0016_type_item_where_clause.txt +++ b/tests/data/parser/inline/0016_type_item_where_clause.txt @@ -3,14 +3,15 @@ FILE@[0; 31) TYPE_KW@[0; 4) WHITESPACE@[4; 5) IDENT@[5; 8) "Foo" - WHITESPACE@[8; 9) - WHERE_KW@[9; 14) - WHITESPACE@[14; 15) - IDENT@[15; 18) "Foo" - COLON@[18; 19) - WHITESPACE@[19; 20) - IDENT@[20; 24) "Copy" - WHITESPACE@[24; 25) + WHERE_CLAUSE@[8; 25) + WHITESPACE@[8; 9) + WHERE_KW@[9; 14) + WHITESPACE@[14; 15) + IDENT@[15; 18) "Foo" + COLON@[18; 19) + WHITESPACE@[19; 20) + IDENT@[20; 24) "Copy" + WHITESPACE@[24; 25) EQ@[25; 26) WHITESPACE@[26; 27) L_PAREN@[27; 28)