aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grammar.ron14
-rw-r--r--src/parser/event_parser/grammar/items/mod.rs43
-rw-r--r--src/syntax_kinds.rs20
-rw-r--r--tests/data/parser/ok/0021_extern_fn.rs8
-rw-r--r--tests/data/parser/ok/0021_extern_fn.txt47
-rw-r--r--tests/data/parser/ok/0022_empty_extern_block.rs5
-rw-r--r--tests/data/parser/ok/0022_empty_extern_block.txt19
7 files changed, 139 insertions, 17 deletions
diff --git a/grammar.ron b/grammar.ron
index 8585fd2d4..44826c779 100644
--- a/grammar.ron
+++ b/grammar.ron
@@ -78,17 +78,20 @@ Grammar(
78 ], 78 ],
79 nodes: [ 79 nodes: [
80 "FILE", 80 "FILE",
81
81 "STRUCT_ITEM", 82 "STRUCT_ITEM",
82 "ENUM_ITEM", 83 "ENUM_ITEM",
83 "ENUM_VARIANT",
84 "NAMED_FIELD",
85 "POS_FIELD",
86 "FN_ITEM", 84 "FN_ITEM",
87 "EXTERN_CRATE_ITEM", 85 "EXTERN_CRATE_ITEM",
88 "ATTR",
89 "META_ITEM",
90 "MOD_ITEM", 86 "MOD_ITEM",
91 "USE_ITEM", 87 "USE_ITEM",
88
89 "EXTERN_BLOCK",
90 "ENUM_VARIANT",
91 "NAMED_FIELD",
92 "POS_FIELD",
93 "ATTR",
94 "META_ITEM", // not an item actually
92 "USE_TREE", 95 "USE_TREE",
93 "PATH", 96 "PATH",
94 "PATH_SEGMENT", 97 "PATH_SEGMENT",
@@ -98,5 +101,6 @@ Grammar(
98 "TYPE_PARAM_LIST", 101 "TYPE_PARAM_LIST",
99 "LIFETIME_PARAM", 102 "LIFETIME_PARAM",
100 "TYPE_PARAM", 103 "TYPE_PARAM",
104 "ABI",
101 ] 105 ]
102) 106)
diff --git a/src/parser/event_parser/grammar/items/mod.rs b/src/parser/event_parser/grammar/items/mod.rs
index 4d8783735..a6d8f375c 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) {
19 visibility(p); 19 visibility(p);
20 let la = p.nth(1); 20 let la = p.nth(1);
21 let item_kind = match p.current() { 21 let item_kind = match p.current() {
22 USE_KW => {
23 use_item(p);
24 USE_ITEM
25 }
22 EXTERN_KW if la == CRATE_KW => { 26 EXTERN_KW if la == CRATE_KW => {
23 extern_crate_item(p); 27 extern_crate_item(p);
24 EXTERN_CRATE_ITEM 28 EXTERN_CRATE_ITEM
25 } 29 }
30 EXTERN_KW => {
31 abi(p);
32 match p.current() {
33 FN_KW => {
34 fn_item(p);
35 FN_ITEM
36 }
37 L_CURLY => {
38 extern_block(p);
39 EXTERN_BLOCK
40 }
41 _ => {
42 item.abandon(p);
43 p.error().message("expected `fn` or `{`").emit();
44 return;
45 }
46 }
47 }
26 MOD_KW => { 48 MOD_KW => {
27 mod_item(p); 49 mod_item(p);
28 MOD_ITEM 50 MOD_ITEM
29 } 51 }
30 USE_KW => {
31 use_item(p);
32 USE_ITEM
33 }
34 STRUCT_KW => { 52 STRUCT_KW => {
35 structs::struct_item(p); 53 structs::struct_item(p);
36 STRUCT_ITEM 54 STRUCT_ITEM
@@ -155,6 +173,12 @@ fn mod_item(p: &mut Parser) {
155 } 173 }
156} 174}
157 175
176fn extern_block(p: &mut Parser) {
177 assert!(p.at(L_CURLY));
178 p.bump();
179 p.expect(R_CURLY);
180}
181
158pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool { 182pub(super) fn is_use_tree_start(kind: SyntaxKind) -> bool {
159 kind == STAR || kind == L_CURLY 183 kind == STAR || kind == L_CURLY
160} 184}
@@ -225,6 +249,17 @@ fn use_item(p: &mut Parser) {
225 } 249 }
226} 250}
227 251
252fn abi(p: &mut Parser) {
253 assert!(p.at(EXTERN_KW));
254 let abi = p.start();
255 p.bump();
256 match p.current() {
257 STRING | RAW_STRING => p.bump(),
258 _ => (),
259 }
260 abi.complete(p, ABI);
261}
262
228fn fn_item(p: &mut Parser) { 263fn fn_item(p: &mut Parser) {
229 assert!(p.at(FN_KW)); 264 assert!(p.at(FN_KW));
230 p.bump(); 265 p.bump();
diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs
index cd4c753a9..7577fa037 100644
--- a/src/syntax_kinds.rs
+++ b/src/syntax_kinds.rs
@@ -82,15 +82,16 @@ pub enum SyntaxKind {
82 FILE, 82 FILE,
83 STRUCT_ITEM, 83 STRUCT_ITEM,
84 ENUM_ITEM, 84 ENUM_ITEM,
85 FN_ITEM,
86 EXTERN_CRATE_ITEM,
87 MOD_ITEM,
88 USE_ITEM,
89 EXTERN_BLOCK,
85 ENUM_VARIANT, 90 ENUM_VARIANT,
86 NAMED_FIELD, 91 NAMED_FIELD,
87 POS_FIELD, 92 POS_FIELD,
88 FN_ITEM,
89 EXTERN_CRATE_ITEM,
90 ATTR, 93 ATTR,
91 META_ITEM, 94 META_ITEM,
92 MOD_ITEM,
93 USE_ITEM,
94 USE_TREE, 95 USE_TREE,
95 PATH, 96 PATH,
96 PATH_SEGMENT, 97 PATH_SEGMENT,
@@ -100,6 +101,7 @@ pub enum SyntaxKind {
100 TYPE_PARAM_LIST, 101 TYPE_PARAM_LIST,
101 LIFETIME_PARAM, 102 LIFETIME_PARAM,
102 TYPE_PARAM, 103 TYPE_PARAM,
104 ABI,
103 105
104 // Technical SyntaxKinds: they appear temporally during parsing, 106 // Technical SyntaxKinds: they appear temporally during parsing,
105 // but never end up in the final tree 107 // but never end up in the final tree
@@ -189,15 +191,16 @@ impl SyntaxKind {
189 FILE => &SyntaxInfo { name: "FILE" }, 191 FILE => &SyntaxInfo { name: "FILE" },
190 STRUCT_ITEM => &SyntaxInfo { name: "STRUCT_ITEM" }, 192 STRUCT_ITEM => &SyntaxInfo { name: "STRUCT_ITEM" },
191 ENUM_ITEM => &SyntaxInfo { name: "ENUM_ITEM" }, 193 ENUM_ITEM => &SyntaxInfo { name: "ENUM_ITEM" },
194 FN_ITEM => &SyntaxInfo { name: "FN_ITEM" },
195 EXTERN_CRATE_ITEM => &SyntaxInfo { name: "EXTERN_CRATE_ITEM" },
196 MOD_ITEM => &SyntaxInfo { name: "MOD_ITEM" },
197 USE_ITEM => &SyntaxInfo { name: "USE_ITEM" },
198 EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
192 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, 199 ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
193 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, 200 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
194 POS_FIELD => &SyntaxInfo { name: "POS_FIELD" }, 201 POS_FIELD => &SyntaxInfo { name: "POS_FIELD" },
195 FN_ITEM => &SyntaxInfo { name: "FN_ITEM" },
196 EXTERN_CRATE_ITEM => &SyntaxInfo { name: "EXTERN_CRATE_ITEM" },
197 ATTR => &SyntaxInfo { name: "ATTR" }, 202 ATTR => &SyntaxInfo { name: "ATTR" },
198 META_ITEM => &SyntaxInfo { name: "META_ITEM" }, 203 META_ITEM => &SyntaxInfo { name: "META_ITEM" },
199 MOD_ITEM => &SyntaxInfo { name: "MOD_ITEM" },
200 USE_ITEM => &SyntaxInfo { name: "USE_ITEM" },
201 USE_TREE => &SyntaxInfo { name: "USE_TREE" }, 204 USE_TREE => &SyntaxInfo { name: "USE_TREE" },
202 PATH => &SyntaxInfo { name: "PATH" }, 205 PATH => &SyntaxInfo { name: "PATH" },
203 PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" }, 206 PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" },
@@ -207,6 +210,7 @@ impl SyntaxKind {
207 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, 210 TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
208 LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" }, 211 LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
209 TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" }, 212 TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
213 ABI => &SyntaxInfo { name: "ABI" },
210 214
211 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, 215 TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
212 EOF => &SyntaxInfo { name: "EOF" }, 216 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 000000000..e929eef74
--- /dev/null
+++ b/tests/data/parser/ok/0021_extern_fn.rs
@@ -0,0 +1,8 @@
1extern fn foo() {
2}
3
4extern "C" fn bar() {
5}
6
7extern r"D" fn baz() {
8}
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 000000000..43575bdf3
--- /dev/null
+++ b/tests/data/parser/ok/0021_extern_fn.txt
@@ -0,0 +1,47 @@
1FILE@[0; 71)
2 FN_ITEM@[0; 21)
3 ABI@[0; 7)
4 EXTERN_KW@[0; 6)
5 WHITESPACE@[6; 7)
6 FN_KW@[7; 9)
7 WHITESPACE@[9; 10)
8 IDENT@[10; 13) "foo"
9 L_PAREN@[13; 14)
10 R_PAREN@[14; 15)
11 WHITESPACE@[15; 16)
12 L_CURLY@[16; 17)
13 WHITESPACE@[17; 18)
14 R_CURLY@[18; 19)
15 WHITESPACE@[19; 21)
16 FN_ITEM@[21; 46)
17 ABI@[21; 32)
18 EXTERN_KW@[21; 27)
19 WHITESPACE@[27; 28)
20 STRING@[28; 31)
21 WHITESPACE@[31; 32)
22 FN_KW@[32; 34)
23 WHITESPACE@[34; 35)
24 IDENT@[35; 38) "bar"
25 L_PAREN@[38; 39)
26 R_PAREN@[39; 40)
27 WHITESPACE@[40; 41)
28 L_CURLY@[41; 42)
29 WHITESPACE@[42; 43)
30 R_CURLY@[43; 44)
31 WHITESPACE@[44; 46)
32 FN_ITEM@[46; 71)
33 ABI@[46; 58)
34 EXTERN_KW@[46; 52)
35 WHITESPACE@[52; 53)
36 RAW_STRING@[53; 57)
37 WHITESPACE@[57; 58)
38 FN_KW@[58; 60)
39 WHITESPACE@[60; 61)
40 IDENT@[61; 64) "baz"
41 L_PAREN@[64; 65)
42 R_PAREN@[65; 66)
43 WHITESPACE@[66; 67)
44 L_CURLY@[67; 68)
45 WHITESPACE@[68; 69)
46 R_CURLY@[69; 70)
47 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 000000000..f5fe0e6ef
--- /dev/null
+++ b/tests/data/parser/ok/0022_empty_extern_block.rs
@@ -0,0 +1,5 @@
1extern {
2}
3
4extern "C" {
5}
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 000000000..789cba364
--- /dev/null
+++ b/tests/data/parser/ok/0022_empty_extern_block.txt
@@ -0,0 +1,19 @@
1FILE@[0; 27)
2 EXTERN_BLOCK@[0; 12)
3 ABI@[0; 7)
4 EXTERN_KW@[0; 6)
5 WHITESPACE@[6; 7)
6 L_CURLY@[7; 8)
7 WHITESPACE@[8; 9)
8 R_CURLY@[9; 10)
9 WHITESPACE@[10; 12)
10 EXTERN_BLOCK@[12; 27)
11 ABI@[12; 23)
12 EXTERN_KW@[12; 18)
13 WHITESPACE@[18; 19)
14 STRING@[19; 22)
15 WHITESPACE@[22; 23)
16 L_CURLY@[23; 24)
17 WHITESPACE@[24; 25)
18 R_CURLY@[25; 26)
19 WHITESPACE@[26; 27)