diff options
Diffstat (limited to 'crates/ra_syntax/src/grammar')
-rw-r--r-- | crates/ra_syntax/src/grammar/items/use_item.rs | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/crates/ra_syntax/src/grammar/items/use_item.rs b/crates/ra_syntax/src/grammar/items/use_item.rs index 1ee4349fd..b3c78f351 100644 --- a/crates/ra_syntax/src/grammar/items/use_item.rs +++ b/crates/ra_syntax/src/grammar/items/use_item.rs | |||
@@ -7,25 +7,75 @@ pub(super) fn use_item(p: &mut Parser) { | |||
7 | p.expect(SEMI); | 7 | p.expect(SEMI); |
8 | } | 8 | } |
9 | 9 | ||
10 | /// Parse a use 'tree', such as `some::path` in `use some::path;` | ||
11 | /// Note that this is called both by `use_item` and `use_tree_list`, | ||
12 | /// so handles both `some::path::{inner::path}` and `inner::path` in | ||
13 | /// `use some::path::{inner::path};` | ||
10 | fn use_tree(p: &mut Parser) { | 14 | fn use_tree(p: &mut Parser) { |
11 | let la = p.nth(1); | 15 | let la = p.nth(1); |
12 | let m = p.start(); | 16 | let m = p.start(); |
13 | match (p.current(), la) { | 17 | match (p.current(), la) { |
18 | // Finish the use_tree for cases of e.g. | ||
19 | // `use some::path::{self, *};` or `use *;` | ||
20 | // This does not handle cases such as `use some::path::*` | ||
21 | // N.B. in Rust 2015 `use *;` imports all from crate root | ||
22 | // however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates') | ||
23 | // TODO: Add this error (if not out of scope) | ||
24 | |||
25 | // test use_star | ||
26 | // use *; | ||
27 | // use ::*; | ||
28 | // use some::path::{*}; | ||
29 | // use some::path::{::*}; | ||
14 | (STAR, _) => p.bump(), | 30 | (STAR, _) => p.bump(), |
15 | (COLONCOLON, STAR) => { | 31 | (COLONCOLON, STAR) => { |
32 | // Parse `use ::*;`, which imports all from the crate root in Rust 2015 | ||
33 | // This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`) | ||
34 | // but still parses and errors later: ('crate root in paths can only be used in start position') | ||
35 | // TODO: Add this error (if not out of scope) | ||
36 | // In Rust 2018, it is always invalid (see above) | ||
16 | p.bump(); | 37 | p.bump(); |
17 | p.bump(); | 38 | p.bump(); |
18 | } | 39 | } |
40 | // Open a use tree list | ||
41 | // Handles cases such as `use {some::path};` or `{inner::path}` in | ||
42 | // `use some::path::{{inner::path}, other::path}` | ||
43 | |||
44 | // test use_tree_list | ||
45 | // use {crate::path::from::root, or::path::from::crate_name}; // Rust 2018 (with a crate named `or`) | ||
46 | // use {path::from::root}; // Rust 2015 | ||
47 | // use ::{some::arbritrary::path}; // Rust 2015 | ||
48 | // use ::{{{crate::export}}}; // Nonsensical but perfectly legal nestnig | ||
19 | (L_CURLY, _) | (COLONCOLON, L_CURLY) => { | 49 | (L_CURLY, _) | (COLONCOLON, L_CURLY) => { |
20 | if p.at(COLONCOLON) { | 50 | if p.at(COLONCOLON) { |
21 | p.bump(); | 51 | p.bump(); |
22 | } | 52 | } |
23 | use_tree_list(p); | 53 | use_tree_list(p); |
24 | } | 54 | } |
55 | // Parse a 'standard' path. | ||
56 | // Also handles aliases (e.g. `use something as something_else`) | ||
57 | |||
58 | // test use_path | ||
59 | // use ::crate_name; // Rust 2018 - All flavours | ||
60 | // use crate_name; // Rust 2018 - Anchored paths | ||
61 | // use item_in_scope_or_crate_name; // Rust 2018 - Uniform Paths | ||
62 | // | ||
63 | // use self::module::Item; | ||
64 | // use crate::Item; | ||
65 | // use self::some::Struct; | ||
66 | // use crate_name::some_item; | ||
25 | _ if paths::is_path_start(p) => { | 67 | _ if paths::is_path_start(p) => { |
26 | paths::use_path(p); | 68 | paths::use_path(p); |
27 | match p.current() { | 69 | match p.current() { |
28 | AS_KW => { | 70 | AS_KW => { |
71 | // test use_alias | ||
72 | // use some::path as some_name; | ||
73 | // use some::{ | ||
74 | // other::path as some_other_name, | ||
75 | // different::path as different_name, | ||
76 | // yet::another::path, | ||
77 | // running::out::of::synonyms::for::different::* | ||
78 | // }; | ||
29 | opt_alias(p); | 79 | opt_alias(p); |
30 | } | 80 | } |
31 | COLONCOLON => { | 81 | COLONCOLON => { |
@@ -34,6 +84,9 @@ fn use_tree(p: &mut Parser) { | |||
34 | STAR => { | 84 | STAR => { |
35 | p.bump(); | 85 | p.bump(); |
36 | } | 86 | } |
87 | // test use_tree_list_after_path | ||
88 | // use crate::{Item}; | ||
89 | // use self::{Item}; | ||
37 | L_CURLY => use_tree_list(p), | 90 | L_CURLY => use_tree_list(p), |
38 | _ => { | 91 | _ => { |
39 | // is this unreachable? | 92 | // is this unreachable? |
@@ -46,7 +99,7 @@ fn use_tree(p: &mut Parser) { | |||
46 | } | 99 | } |
47 | _ => { | 100 | _ => { |
48 | m.abandon(p); | 101 | m.abandon(p); |
49 | p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`"); | 102 | p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super` or an indentifier"); |
50 | return; | 103 | return; |
51 | } | 104 | } |
52 | } | 105 | } |