]> git.lizzy.rs Git - rust.git/blob - crates/ra_parser/src/grammar.rs
Touch up TokenSet a bit
[rust.git] / crates / ra_parser / src / grammar.rs
1 //! This is the actual "grammar" of the Rust language.
2 //!
3 //! Each function in this module and its children corresponds
4 //! to a production of the format grammar. Submodules roughly
5 //! correspond to different *areas* of the grammar. By convention,
6 //! each submodule starts with `use super::*` import and exports
7 //! "public" productions via `pub(super)`.
8 //!
9 //! See docs for `Parser` to learn about API, available to the grammar,
10 //! and see docs for `Event` to learn how this actually manages to
11 //! produce parse trees.
12 //!
13 //! Code in this module also contains inline tests, which start with
14 //! `// test name-of-the-test` comment and look like this:
15 //!
16 //! ```
17 //! // test function_with_zero_parameters
18 //! // fn foo() {}
19 //! ```
20 //!
21 //! After adding a new inline-test, run `cargo collect-tests` to extract
22 //! it as a standalone text-fixture into `tests/data/parser/inline`, and
23 //! run `cargo test` once to create the "gold" value.
24 //!
25 //! Coding convention: rules like `where_clause` always produce either a
26 //! node or an error, rules like `opt_where_clause` may produce nothing.
27 //! Non-opt rules typically start with `assert!(p.at(FIRST_TOKEN))`, the
28 //! caller is responsible for branching on the first token.
29 mod attributes;
30 mod expressions;
31 mod items;
32 mod params;
33 mod paths;
34 mod patterns;
35 mod type_args;
36 mod type_params;
37 mod types;
38
39 use crate::{
40     parser::{CompletedMarker, Marker, Parser},
41     SyntaxKind::{self, *},
42     TokenSet,
43 };
44
45 pub(crate) fn root(p: &mut Parser) {
46     let m = p.start();
47     p.eat(SHEBANG);
48     items::mod_contents(p, false);
49     m.complete(p, SOURCE_FILE);
50 }
51
52 /// Various pieces of syntax that can be parsed by macros by example
53 pub(crate) mod fragments {
54     use super::*;
55
56     pub(crate) use super::{
57         expressions::block, paths::type_path as path, patterns::pattern, types::type_,
58     };
59
60     pub(crate) fn expr(p: &mut Parser) {
61         let _ = expressions::expr(p);
62     }
63
64     pub(crate) fn stmt(p: &mut Parser) {
65         expressions::stmt(p, expressions::StmtWithSemi::No)
66     }
67
68     pub(crate) fn opt_visibility(p: &mut Parser) {
69         let _ = super::opt_visibility(p);
70     }
71
72     // Parse a meta item , which excluded [], e.g : #[ MetaItem ]
73     pub(crate) fn meta_item(p: &mut Parser) {
74         fn is_delimiter(p: &mut Parser) -> bool {
75             match p.current() {
76                 T!['{'] | T!['('] | T!['['] => true,
77                 _ => false,
78             }
79         }
80
81         if is_delimiter(p) {
82             items::token_tree(p);
83             return;
84         }
85
86         let m = p.start();
87         while !p.at(EOF) {
88             if is_delimiter(p) {
89                 items::token_tree(p);
90                 break;
91             } else {
92                 // https://doc.rust-lang.org/reference/attributes.html
93                 // https://doc.rust-lang.org/reference/paths.html#simple-paths
94                 // The start of an meta must be a simple path
95                 match p.current() {
96                     IDENT | T![::] | T![super] | T![self] | T![crate] => p.bump_any(),
97                     T![=] => {
98                         p.bump_any();
99                         match p.current() {
100                             c if c.is_literal() => p.bump_any(),
101                             T![true] | T![false] => p.bump_any(),
102                             _ => {}
103                         }
104                         break;
105                     }
106                     _ => break,
107                 }
108             }
109         }
110
111         m.complete(p, TOKEN_TREE);
112     }
113
114     pub(crate) fn item(p: &mut Parser) {
115         items::item_or_macro(p, true, items::ItemFlavor::Mod)
116     }
117
118     pub(crate) fn macro_items(p: &mut Parser) {
119         let m = p.start();
120         items::mod_contents(p, false);
121         m.complete(p, MACRO_ITEMS);
122     }
123
124     pub(crate) fn macro_stmts(p: &mut Parser) {
125         let m = p.start();
126
127         while !p.at(EOF) {
128             if p.at(T![;]) {
129                 p.bump(T![;]);
130                 continue;
131             }
132
133             expressions::stmt(p, expressions::StmtWithSemi::Optional);
134         }
135
136         m.complete(p, MACRO_STMTS);
137     }
138 }
139
140 pub(crate) fn reparser(
141     node: SyntaxKind,
142     first_child: Option<SyntaxKind>,
143     parent: Option<SyntaxKind>,
144 ) -> Option<fn(&mut Parser)> {
145     let res = match node {
146         BLOCK => expressions::naked_block,
147         RECORD_FIELD_DEF_LIST => items::record_field_def_list,
148         RECORD_FIELD_LIST => items::record_field_list,
149         ENUM_VARIANT_LIST => items::enum_variant_list,
150         MATCH_ARM_LIST => items::match_arm_list,
151         USE_TREE_LIST => items::use_tree_list,
152         EXTERN_ITEM_LIST => items::extern_item_list,
153         TOKEN_TREE if first_child? == T!['{'] => items::token_tree,
154         ITEM_LIST => match parent? {
155             IMPL_BLOCK => items::impl_item_list,
156             TRAIT_DEF => items::trait_item_list,
157             MODULE => items::mod_item_list,
158             _ => return None,
159         },
160         _ => return None,
161     };
162     Some(res)
163 }
164
165 #[derive(Clone, Copy, PartialEq, Eq)]
166 enum BlockLike {
167     Block,
168     NotBlock,
169 }
170
171 impl BlockLike {
172     fn is_block(self) -> bool {
173         self == BlockLike::Block
174     }
175 }
176
177 fn opt_visibility(p: &mut Parser) -> bool {
178     match p.current() {
179         T![pub] => {
180             let m = p.start();
181             p.bump(T![pub]);
182             if p.at(T!['(']) {
183                 match p.nth(1) {
184                     // test crate_visibility
185                     // pub(crate) struct S;
186                     // pub(self) struct S;
187                     // pub(self) struct S;
188                     // pub(self) struct S;
189                     T![crate] | T![self] | T![super] => {
190                         p.bump_any();
191                         p.bump_any();
192                         p.expect(T![')']);
193                     }
194                     T![in] => {
195                         p.bump_any();
196                         p.bump_any();
197                         paths::use_path(p);
198                         p.expect(T![')']);
199                     }
200                     _ => (),
201                 }
202             }
203             m.complete(p, VISIBILITY);
204         }
205         // test crate_keyword_vis
206         // crate fn main() { }
207         // struct S { crate field: u32 }
208         // struct T(crate u32);
209         //
210         // test crate_keyword_path
211         // fn foo() { crate::foo(); }
212         T![crate] if !p.nth_at(1, T![::]) => {
213             let m = p.start();
214             p.bump(T![crate]);
215             m.complete(p, VISIBILITY);
216         }
217         _ => return false,
218     }
219     true
220 }
221
222 fn opt_alias(p: &mut Parser) {
223     if p.at(T![as]) {
224         let m = p.start();
225         p.bump(T![as]);
226         if !p.eat(T![_]) {
227             name(p);
228         }
229         m.complete(p, ALIAS);
230     }
231 }
232
233 fn abi(p: &mut Parser) {
234     assert!(p.at(T![extern]));
235     let abi = p.start();
236     p.bump(T![extern]);
237     match p.current() {
238         STRING | RAW_STRING => p.bump_any(),
239         _ => (),
240     }
241     abi.complete(p, ABI);
242 }
243
244 fn opt_fn_ret_type(p: &mut Parser) -> bool {
245     if p.at(T![->]) {
246         let m = p.start();
247         p.bump(T![->]);
248         types::type_(p);
249         m.complete(p, RET_TYPE);
250         true
251     } else {
252         false
253     }
254 }
255
256 fn name_r(p: &mut Parser, recovery: TokenSet) {
257     if p.at(IDENT) {
258         let m = p.start();
259         p.bump(IDENT);
260         m.complete(p, NAME);
261     } else {
262         p.err_recover("expected a name", recovery);
263     }
264 }
265
266 fn name(p: &mut Parser) {
267     name_r(p, TokenSet::EMPTY)
268 }
269
270 fn name_ref(p: &mut Parser) {
271     if p.at(IDENT) {
272         let m = p.start();
273         p.bump(IDENT);
274         m.complete(p, NAME_REF);
275     } else if p.at(T![self]) {
276         let m = p.start();
277         p.bump(T![self]);
278         m.complete(p, T![self]);
279     } else {
280         p.err_and_bump("expected identifier");
281     }
282 }
283
284 fn name_ref_or_index(p: &mut Parser) {
285     if p.at(IDENT) || p.at(INT_NUMBER) {
286         let m = p.start();
287         p.bump_any();
288         m.complete(p, NAME_REF);
289     } else {
290         p.err_and_bump("expected identifier");
291     }
292 }
293
294 fn error_block(p: &mut Parser, message: &str) {
295     assert!(p.at(T!['{']));
296     let m = p.start();
297     p.error(message);
298     p.bump(T!['{']);
299     expressions::expr_block_contents(p);
300     p.eat(T!['}']);
301     m.complete(p, ERROR);
302 }