diff --git a/grammar.ron b/grammar.ron index 8585fd2d4de..44826c779c6 100644 --- a/grammar.ron +++ b/grammar.ron @@ -78,17 +78,20 @@ Grammar( ], nodes: [ "FILE", + "STRUCT_ITEM", "ENUM_ITEM", + "FN_ITEM", + "EXTERN_CRATE_ITEM", + "MOD_ITEM", + "USE_ITEM", + + "EXTERN_BLOCK", "ENUM_VARIANT", "NAMED_FIELD", "POS_FIELD", - "FN_ITEM", - "EXTERN_CRATE_ITEM", "ATTR", - "META_ITEM", - "MOD_ITEM", - "USE_ITEM", + "META_ITEM", // not an item actually "USE_TREE", "PATH", "PATH_SEGMENT", @@ -98,5 +101,6 @@ Grammar( "TYPE_PARAM_LIST", "LIFETIME_PARAM", "TYPE_PARAM", + "ABI", ] ) diff --git a/src/parser/event_parser/grammar/items/mod.rs b/src/parser/event_parser/grammar/items/mod.rs index 4d878373549..a6d8f375cd3 100644 --- a/src/parser/event_parser/grammar/items/mod.rs +++ b/src/parser/event_parser/grammar/items/mod.rs @@ -19,18 +19,36 @@ fn item(p: &mut Parser) { visibility(p); let la = p.nth(1); let item_kind = match p.current() { + USE_KW => { + use_item(p); + USE_ITEM + } EXTERN_KW if la == CRATE_KW => { extern_crate_item(p); EXTERN_CRATE_ITEM } + EXTERN_KW => { + abi(p); + match p.current() { + FN_KW => { + fn_item(p); + FN_ITEM + } + L_CURLY => { + extern_block(p); + EXTERN_BLOCK + } + _ => { + item.abandon(p); + p.error().message("expected `fn` or `{`").emit(); + return; + } + } + } MOD_KW => { mod_item(p); MOD_ITEM } - USE_KW => { - use_item(p); - USE_ITEM - } STRUCT_KW => { structs::struct_item(p); STRUCT_ITEM @@ -155,6 +173,12 @@ fn mod_item(p: &mut Parser) { } } +fn extern_block(p: &mut Parser) { + assert!(p.at(L_CURLY)); + p.bump(); + p.expect(R_CURLY); +} + pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool { kind == STAR || kind == L_CURLY } @@ -225,6 +249,17 @@ fn use_item(p: &mut Parser) { } } +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(); diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index cd4c753a9b7..7577fa03713 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -82,15 +82,16 @@ pub enum SyntaxKind { FILE, STRUCT_ITEM, ENUM_ITEM, + FN_ITEM, + EXTERN_CRATE_ITEM, + MOD_ITEM, + USE_ITEM, + EXTERN_BLOCK, ENUM_VARIANT, NAMED_FIELD, POS_FIELD, - FN_ITEM, - EXTERN_CRATE_ITEM, ATTR, META_ITEM, - MOD_ITEM, - USE_ITEM, USE_TREE, PATH, PATH_SEGMENT, @@ -100,6 +101,7 @@ pub enum SyntaxKind { TYPE_PARAM_LIST, LIFETIME_PARAM, TYPE_PARAM, + ABI, // Technical SyntaxKinds: they appear temporally during parsing, // but never end up in the final tree @@ -189,15 +191,16 @@ impl SyntaxKind { FILE => &SyntaxInfo { name: "FILE" }, STRUCT_ITEM => &SyntaxInfo { name: "STRUCT_ITEM" }, ENUM_ITEM => &SyntaxInfo { name: "ENUM_ITEM" }, + FN_ITEM => &SyntaxInfo { name: "FN_ITEM" }, + EXTERN_CRATE_ITEM => &SyntaxInfo { name: "EXTERN_CRATE_ITEM" }, + MOD_ITEM => &SyntaxInfo { name: "MOD_ITEM" }, + USE_ITEM => &SyntaxInfo { name: "USE_ITEM" }, + EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, POS_FIELD => &SyntaxInfo { name: "POS_FIELD" }, - FN_ITEM => &SyntaxInfo { name: "FN_ITEM" }, - EXTERN_CRATE_ITEM => &SyntaxInfo { name: "EXTERN_CRATE_ITEM" }, ATTR => &SyntaxInfo { name: "ATTR" }, META_ITEM => &SyntaxInfo { name: "META_ITEM" }, - MOD_ITEM => &SyntaxInfo { name: "MOD_ITEM" }, - USE_ITEM => &SyntaxInfo { name: "USE_ITEM" }, USE_TREE => &SyntaxInfo { name: "USE_TREE" }, PATH => &SyntaxInfo { name: "PATH" }, PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" }, @@ -207,6 +210,7 @@ impl SyntaxKind { TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" }, TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" }, + ABI => &SyntaxInfo { name: "ABI" }, TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, EOF => &SyntaxInfo { name: "EOF" }, diff --git a/tests/data/parser/ok/0021_extern_fn.rs b/tests/data/parser/ok/0021_extern_fn.rs new file mode 100644 index 00000000000..e929eef7414 --- /dev/null +++ b/tests/data/parser/ok/0021_extern_fn.rs @@ -0,0 +1,8 @@ +extern fn foo() { +} + +extern "C" fn bar() { +} + +extern r"D" fn baz() { +} diff --git a/tests/data/parser/ok/0021_extern_fn.txt b/tests/data/parser/ok/0021_extern_fn.txt new file mode 100644 index 00000000000..43575bdf349 --- /dev/null +++ b/tests/data/parser/ok/0021_extern_fn.txt @@ -0,0 +1,47 @@ +FILE@[0; 71) + FN_ITEM@[0; 21) + ABI@[0; 7) + EXTERN_KW@[0; 6) + WHITESPACE@[6; 7) + FN_KW@[7; 9) + WHITESPACE@[9; 10) + IDENT@[10; 13) "foo" + L_PAREN@[13; 14) + R_PAREN@[14; 15) + WHITESPACE@[15; 16) + L_CURLY@[16; 17) + WHITESPACE@[17; 18) + R_CURLY@[18; 19) + WHITESPACE@[19; 21) + FN_ITEM@[21; 46) + ABI@[21; 32) + EXTERN_KW@[21; 27) + WHITESPACE@[27; 28) + STRING@[28; 31) + WHITESPACE@[31; 32) + FN_KW@[32; 34) + WHITESPACE@[34; 35) + IDENT@[35; 38) "bar" + L_PAREN@[38; 39) + R_PAREN@[39; 40) + WHITESPACE@[40; 41) + L_CURLY@[41; 42) + WHITESPACE@[42; 43) + R_CURLY@[43; 44) + WHITESPACE@[44; 46) + FN_ITEM@[46; 71) + ABI@[46; 58) + EXTERN_KW@[46; 52) + WHITESPACE@[52; 53) + RAW_STRING@[53; 57) + WHITESPACE@[57; 58) + FN_KW@[58; 60) + WHITESPACE@[60; 61) + IDENT@[61; 64) "baz" + L_PAREN@[64; 65) + R_PAREN@[65; 66) + WHITESPACE@[66; 67) + L_CURLY@[67; 68) + WHITESPACE@[68; 69) + R_CURLY@[69; 70) + WHITESPACE@[70; 71) diff --git a/tests/data/parser/ok/0022_empty_extern_block.rs b/tests/data/parser/ok/0022_empty_extern_block.rs new file mode 100644 index 00000000000..f5fe0e6ef30 --- /dev/null +++ b/tests/data/parser/ok/0022_empty_extern_block.rs @@ -0,0 +1,5 @@ +extern { +} + +extern "C" { +} diff --git a/tests/data/parser/ok/0022_empty_extern_block.txt b/tests/data/parser/ok/0022_empty_extern_block.txt new file mode 100644 index 00000000000..789cba36429 --- /dev/null +++ b/tests/data/parser/ok/0022_empty_extern_block.txt @@ -0,0 +1,19 @@ +FILE@[0; 27) + EXTERN_BLOCK@[0; 12) + ABI@[0; 7) + EXTERN_KW@[0; 6) + WHITESPACE@[6; 7) + L_CURLY@[7; 8) + WHITESPACE@[8; 9) + R_CURLY@[9; 10) + WHITESPACE@[10; 12) + EXTERN_BLOCK@[12; 27) + ABI@[12; 23) + EXTERN_KW@[12; 18) + WHITESPACE@[18; 19) + STRING@[19; 22) + WHITESPACE@[22; 23) + L_CURLY@[23; 24) + WHITESPACE@[24; 25) + R_CURLY@[25; 26) + WHITESPACE@[26; 27)