diff options
26 files changed, 124 insertions, 40 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index bcbd4c60c..4d8412d46 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -142,7 +142,7 @@ impl Attr { | |||
142 | pub fn as_atom(&self) -> Option<SmolStr> { | 142 | pub fn as_atom(&self) -> Option<SmolStr> { |
143 | let tt = self.value()?; | 143 | let tt = self.value()?; |
144 | let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; | 144 | let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; |
145 | if attr.kind() == IDENT { | 145 | if attr.kind().is_ident() { |
146 | Some(attr.leaf_text().unwrap().clone()) | 146 | Some(attr.leaf_text().unwrap().clone()) |
147 | } else { | 147 | } else { |
148 | None | 148 | None |
@@ -153,7 +153,7 @@ impl Attr { | |||
153 | let tt = self.value()?; | 153 | let tt = self.value()?; |
154 | let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?; | 154 | let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?; |
155 | let args = TokenTree::cast(args)?; | 155 | let args = TokenTree::cast(args)?; |
156 | if attr.kind() == IDENT { | 156 | if attr.kind().is_ident() { |
157 | Some((attr.leaf_text().unwrap().clone(), args)) | 157 | Some((attr.leaf_text().unwrap().clone(), args)) |
158 | } else { | 158 | } else { |
159 | None | 159 | None |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 0385183fd..64beb8252 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -102,6 +102,7 @@ Grammar( | |||
102 | tokens: [ | 102 | tokens: [ |
103 | "ERROR", | 103 | "ERROR", |
104 | "IDENT", | 104 | "IDENT", |
105 | "RAW_IDENT", | ||
105 | "UNDERSCORE", | 106 | "UNDERSCORE", |
106 | "WHITESPACE", | 107 | "WHITESPACE", |
107 | "INT_NUMBER", | 108 | "INT_NUMBER", |
@@ -116,6 +117,10 @@ Grammar( | |||
116 | "COMMENT", | 117 | "COMMENT", |
117 | "SHEBANG", | 118 | "SHEBANG", |
118 | ], | 119 | ], |
120 | ident_tokens: [ | ||
121 | "IDENT", | ||
122 | "RAW_IDENT", | ||
123 | ], | ||
119 | nodes: [ | 124 | nodes: [ |
120 | "SOURCE_FILE", | 125 | "SOURCE_FILE", |
121 | 126 | ||
diff --git a/crates/ra_syntax/src/grammar.rs b/crates/ra_syntax/src/grammar.rs index 060c0ccdf..531d0458f 100644 --- a/crates/ra_syntax/src/grammar.rs +++ b/crates/ra_syntax/src/grammar.rs | |||
@@ -140,7 +140,7 @@ fn opt_fn_ret_type(p: &mut Parser) -> bool { | |||
140 | } | 140 | } |
141 | 141 | ||
142 | fn name_r(p: &mut Parser, recovery: TokenSet) { | 142 | fn name_r(p: &mut Parser, recovery: TokenSet) { |
143 | if p.at(IDENT) { | 143 | if p.current().is_ident() { |
144 | let m = p.start(); | 144 | let m = p.start(); |
145 | p.bump(); | 145 | p.bump(); |
146 | m.complete(p, NAME); | 146 | m.complete(p, NAME); |
@@ -154,7 +154,7 @@ fn name(p: &mut Parser) { | |||
154 | } | 154 | } |
155 | 155 | ||
156 | fn name_ref(p: &mut Parser) { | 156 | fn name_ref(p: &mut Parser) { |
157 | if p.at(IDENT) { | 157 | if p.current().is_ident() { |
158 | let m = p.start(); | 158 | let m = p.start(); |
159 | p.bump(); | 159 | p.bump(); |
160 | m.complete(p, NAME_REF); | 160 | m.complete(p, NAME_REF); |
diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs index 2236555e0..107b7cda4 100644 --- a/crates/ra_syntax/src/grammar/expressions.rs +++ b/crates/ra_syntax/src/grammar/expressions.rs | |||
@@ -281,7 +281,7 @@ fn postfix_expr( | |||
281 | // } | 281 | // } |
282 | L_PAREN if allow_calls => call_expr(p, lhs), | 282 | L_PAREN if allow_calls => call_expr(p, lhs), |
283 | L_BRACK if allow_calls => index_expr(p, lhs), | 283 | L_BRACK if allow_calls => index_expr(p, lhs), |
284 | DOT if p.nth(1) == IDENT && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) => { | 284 | DOT if p.nth(1).is_ident() && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) => { |
285 | method_call_expr(p, lhs) | 285 | method_call_expr(p, lhs) |
286 | } | 286 | } |
287 | DOT => field_expr(p, lhs), | 287 | DOT => field_expr(p, lhs), |
@@ -332,7 +332,7 @@ fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | |||
332 | // y.bar::<T>(1, 2,); | 332 | // y.bar::<T>(1, 2,); |
333 | // } | 333 | // } |
334 | fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 334 | fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { |
335 | assert!(p.at(DOT) && p.nth(1) == IDENT && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON)); | 335 | assert!(p.at(DOT) && p.nth(1).is_ident() && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON)); |
336 | let m = lhs.precede(p); | 336 | let m = lhs.precede(p); |
337 | p.bump(); | 337 | p.bump(); |
338 | name_ref(p); | 338 | name_ref(p); |
@@ -352,7 +352,7 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | |||
352 | assert!(p.at(DOT)); | 352 | assert!(p.at(DOT)); |
353 | let m = lhs.precede(p); | 353 | let m = lhs.precede(p); |
354 | p.bump(); | 354 | p.bump(); |
355 | if p.at(IDENT) { | 355 | if p.current().is_ident() { |
356 | name_ref(p) | 356 | name_ref(p) |
357 | } else if p.at(INT_NUMBER) { | 357 | } else if p.at(INT_NUMBER) { |
358 | p.bump() | 358 | p.bump() |
@@ -443,7 +443,7 @@ pub(crate) fn named_field_list(p: &mut Parser) { | |||
443 | p.bump(); | 443 | p.bump(); |
444 | while !p.at(EOF) && !p.at(R_CURLY) { | 444 | while !p.at(EOF) && !p.at(R_CURLY) { |
445 | match p.current() { | 445 | match p.current() { |
446 | IDENT => { | 446 | IDENT | RAW_IDENT => { |
447 | let m = p.start(); | 447 | let m = p.start(); |
448 | name_ref(p); | 448 | name_ref(p); |
449 | if p.eat(COLON) { | 449 | if p.eat(COLON) { |
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs index 167a76551..3fbe22856 100644 --- a/crates/ra_syntax/src/grammar/expressions/atom.rs +++ b/crates/ra_syntax/src/grammar/expressions/atom.rs | |||
@@ -48,6 +48,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = LITERAL_FIRST.union(token_set![ | |||
48 | UNSAFE_KW, | 48 | UNSAFE_KW, |
49 | RETURN_KW, | 49 | RETURN_KW, |
50 | IDENT, | 50 | IDENT, |
51 | RAW_IDENT, | ||
51 | SELF_KW, | 52 | SELF_KW, |
52 | SUPER_KW, | 53 | SUPER_KW, |
53 | CRATE_KW, | 54 | CRATE_KW, |
diff --git a/crates/ra_syntax/src/grammar/items.rs b/crates/ra_syntax/src/grammar/items.rs index 265e84570..c49798444 100644 --- a/crates/ra_syntax/src/grammar/items.rs +++ b/crates/ra_syntax/src/grammar/items.rs | |||
@@ -99,11 +99,11 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { | |||
99 | has_mods = true; | 99 | has_mods = true; |
100 | abi(p); | 100 | abi(p); |
101 | } | 101 | } |
102 | if p.at(IDENT) && p.at_contextual_kw("auto") && p.nth(1) == TRAIT_KW { | 102 | if p.current().is_ident() && p.at_contextual_kw("auto") && p.nth(1) == TRAIT_KW { |
103 | p.bump_remap(AUTO_KW); | 103 | p.bump_remap(AUTO_KW); |
104 | has_mods = true; | 104 | has_mods = true; |
105 | } | 105 | } |
106 | if p.at(IDENT) && p.at_contextual_kw("default") && p.nth(1) == IMPL_KW { | 106 | if p.current().is_ident() && p.at_contextual_kw("default") && p.nth(1) == IMPL_KW { |
107 | p.bump_remap(DEFAULT_KW); | 107 | p.bump_remap(DEFAULT_KW); |
108 | has_mods = true; | 108 | has_mods = true; |
109 | } | 109 | } |
@@ -202,7 +202,7 @@ fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> { | |||
202 | } | 202 | } |
203 | STRUCT_DEF | 203 | STRUCT_DEF |
204 | } | 204 | } |
205 | IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { | 205 | IDENT | RAW_IDENT if p.at_contextual_kw("union") && p.nth(1).is_ident() => { |
206 | // test union_items | 206 | // test union_items |
207 | // union Foo {} | 207 | // union Foo {} |
208 | // union Foo { | 208 | // union Foo { |
@@ -220,7 +220,7 @@ fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> { | |||
220 | use_item::use_item(p); | 220 | use_item::use_item(p); |
221 | USE_ITEM | 221 | USE_ITEM |
222 | } | 222 | } |
223 | CONST_KW if (la == IDENT || la == MUT_KW) => { | 223 | CONST_KW if (la.is_ident() || la == MUT_KW) => { |
224 | consts::const_def(p); | 224 | consts::const_def(p); |
225 | CONST_DEF | 225 | CONST_DEF |
226 | } | 226 | } |
@@ -351,7 +351,7 @@ fn macro_call(p: &mut Parser) -> BlockLike { | |||
351 | 351 | ||
352 | pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike { | 352 | pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike { |
353 | p.expect(EXCL); | 353 | p.expect(EXCL); |
354 | p.eat(IDENT); | 354 | p.eat_one(&[IDENT, RAW_IDENT]); |
355 | match p.current() { | 355 | match p.current() { |
356 | L_CURLY => { | 356 | L_CURLY => { |
357 | token_tree(p); | 357 | token_tree(p); |
diff --git a/crates/ra_syntax/src/grammar/items/nominal.rs b/crates/ra_syntax/src/grammar/items/nominal.rs index 0784fb7b1..897306883 100644 --- a/crates/ra_syntax/src/grammar/items/nominal.rs +++ b/crates/ra_syntax/src/grammar/items/nominal.rs | |||
@@ -70,7 +70,7 @@ pub(crate) fn enum_variant_list(p: &mut Parser) { | |||
70 | } | 70 | } |
71 | let var = p.start(); | 71 | let var = p.start(); |
72 | attributes::outer_attributes(p); | 72 | attributes::outer_attributes(p); |
73 | if p.at(IDENT) { | 73 | if p.current().is_ident() { |
74 | name(p); | 74 | name(p); |
75 | match p.current() { | 75 | match p.current() { |
76 | L_CURLY => named_field_def_list(p), | 76 | L_CURLY => named_field_def_list(p), |
@@ -120,7 +120,7 @@ pub(crate) fn named_field_def_list(p: &mut Parser) { | |||
120 | // } | 120 | // } |
121 | attributes::outer_attributes(p); | 121 | attributes::outer_attributes(p); |
122 | opt_visibility(p); | 122 | opt_visibility(p); |
123 | if p.at(IDENT) { | 123 | if p.current().is_ident() { |
124 | name(p); | 124 | name(p); |
125 | p.expect(COLON); | 125 | p.expect(COLON); |
126 | types::type_(p); | 126 | types::type_(p); |
diff --git a/crates/ra_syntax/src/grammar/items/traits.rs b/crates/ra_syntax/src/grammar/items/traits.rs index 0a0621753..a78bbba2b 100644 --- a/crates/ra_syntax/src/grammar/items/traits.rs +++ b/crates/ra_syntax/src/grammar/items/traits.rs | |||
@@ -112,7 +112,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool { | |||
112 | if p.nth(1) == POUND || p.nth(1) == R_ANGLE { | 112 | if p.nth(1) == POUND || p.nth(1) == R_ANGLE { |
113 | return true; | 113 | return true; |
114 | } | 114 | } |
115 | (p.nth(1) == LIFETIME || p.nth(1) == IDENT) | 115 | (p.nth(1) == LIFETIME || p.nth(1).is_ident()) |
116 | && (p.nth(2) == R_ANGLE || p.nth(2) == COMMA || p.nth(2) == COLON || p.nth(2) == EQ) | 116 | && (p.nth(2) == R_ANGLE || p.nth(2) == COMMA || p.nth(2) == COLON || p.nth(2) == EQ) |
117 | } | 117 | } |
118 | 118 | ||
diff --git a/crates/ra_syntax/src/grammar/params.rs b/crates/ra_syntax/src/grammar/params.rs index 13158429a..ada07c17e 100644 --- a/crates/ra_syntax/src/grammar/params.rs +++ b/crates/ra_syntax/src/grammar/params.rs | |||
@@ -84,9 +84,9 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { | |||
84 | // trait Foo { | 84 | // trait Foo { |
85 | // fn bar(_: u64); | 85 | // fn bar(_: u64); |
86 | // } | 86 | // } |
87 | if (la0 == IDENT || la0 == UNDERSCORE) && la1 == COLON | 87 | if (la0.is_ident() || la0 == UNDERSCORE) && la1 == COLON |
88 | || la0 == AMP && la1 == IDENT && la2 == COLON | 88 | || la0 == AMP && la1.is_ident() && la2 == COLON |
89 | || la0 == AMP && la1 == MUT_KW && la2 == IDENT && la3 == COLON | 89 | || la0 == AMP && la1 == MUT_KW && la2.is_ident() && la3 == COLON |
90 | { | 90 | { |
91 | patterns::pattern(p); | 91 | patterns::pattern(p); |
92 | types::ascription(p); | 92 | types::ascription(p); |
diff --git a/crates/ra_syntax/src/grammar/paths.rs b/crates/ra_syntax/src/grammar/paths.rs index 33a11886c..0e1c1d334 100644 --- a/crates/ra_syntax/src/grammar/paths.rs +++ b/crates/ra_syntax/src/grammar/paths.rs | |||
@@ -1,11 +1,11 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | pub(super) const PATH_FIRST: TokenSet = | 3 | pub(super) const PATH_FIRST: TokenSet = |
4 | token_set![IDENT, SELF_KW, SUPER_KW, CRATE_KW, COLONCOLON, L_ANGLE]; | 4 | token_set![IDENT, RAW_IDENT, SELF_KW, SUPER_KW, CRATE_KW, COLONCOLON, L_ANGLE]; |
5 | 5 | ||
6 | pub(super) fn is_path_start(p: &Parser) -> bool { | 6 | pub(super) fn is_path_start(p: &Parser) -> bool { |
7 | match p.current() { | 7 | match p.current() { |
8 | IDENT | SELF_KW | SUPER_KW | CRATE_KW | COLONCOLON => true, | 8 | IDENT | RAW_IDENT | SELF_KW | SUPER_KW | CRATE_KW | COLONCOLON => true, |
9 | _ => false, | 9 | _ => false, |
10 | } | 10 | } |
11 | } | 11 | } |
@@ -70,7 +70,7 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) { | |||
70 | p.eat(COLONCOLON); | 70 | p.eat(COLONCOLON); |
71 | } | 71 | } |
72 | match p.current() { | 72 | match p.current() { |
73 | IDENT => { | 73 | IDENT | RAW_IDENT => { |
74 | name_ref(p); | 74 | name_ref(p); |
75 | opt_path_type_args(p, mode); | 75 | opt_path_type_args(p, mode); |
76 | } | 76 | } |
diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs index 1ac5efdf6..925eabe1b 100644 --- a/crates/ra_syntax/src/grammar/patterns.rs +++ b/crates/ra_syntax/src/grammar/patterns.rs | |||
@@ -37,7 +37,7 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { | |||
37 | let la1 = p.nth(1); | 37 | let la1 = p.nth(1); |
38 | if la0 == REF_KW | 38 | if la0 == REF_KW |
39 | || la0 == MUT_KW | 39 | || la0 == MUT_KW |
40 | || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) | 40 | || (la0.is_ident() && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) |
41 | { | 41 | { |
42 | return Some(bind_pat(p, true)); | 42 | return Some(bind_pat(p, true)); |
43 | } | 43 | } |
@@ -128,7 +128,7 @@ fn field_pat_list(p: &mut Parser) { | |||
128 | while !p.at(EOF) && !p.at(R_CURLY) { | 128 | while !p.at(EOF) && !p.at(R_CURLY) { |
129 | match p.current() { | 129 | match p.current() { |
130 | DOTDOT => p.bump(), | 130 | DOTDOT => p.bump(), |
131 | IDENT if p.nth(1) == COLON => field_pat(p), | 131 | IDENT | RAW_IDENT if p.nth(1) == COLON => field_pat(p), |
132 | L_CURLY => error_block(p, "expected ident"), | 132 | L_CURLY => error_block(p, "expected ident"), |
133 | _ => { | 133 | _ => { |
134 | bind_pat(p, false); | 134 | bind_pat(p, false); |
@@ -143,7 +143,7 @@ fn field_pat_list(p: &mut Parser) { | |||
143 | } | 143 | } |
144 | 144 | ||
145 | fn field_pat(p: &mut Parser) { | 145 | fn field_pat(p: &mut Parser) { |
146 | assert!(p.at(IDENT)); | 146 | assert!(p.current().is_ident()); |
147 | assert!(p.nth(1) == COLON); | 147 | assert!(p.nth(1) == COLON); |
148 | 148 | ||
149 | let m = p.start(); | 149 | let m = p.start(); |
diff --git a/crates/ra_syntax/src/grammar/type_args.rs b/crates/ra_syntax/src/grammar/type_args.rs index f889419c5..469595d71 100644 --- a/crates/ra_syntax/src/grammar/type_args.rs +++ b/crates/ra_syntax/src/grammar/type_args.rs | |||
@@ -34,7 +34,7 @@ fn type_arg(p: &mut Parser) { | |||
34 | p.bump(); | 34 | p.bump(); |
35 | m.complete(p, LIFETIME_ARG); | 35 | m.complete(p, LIFETIME_ARG); |
36 | } | 36 | } |
37 | IDENT if p.nth(1) == EQ => { | 37 | IDENT | RAW_IDENT if p.nth(1) == EQ => { |
38 | name_ref(p); | 38 | name_ref(p); |
39 | p.bump(); | 39 | p.bump(); |
40 | types::type_(p); | 40 | types::type_(p); |
diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs index 1ec813b3e..3cebd0675 100644 --- a/crates/ra_syntax/src/grammar/type_params.rs +++ b/crates/ra_syntax/src/grammar/type_params.rs | |||
@@ -15,7 +15,7 @@ fn type_param_list(p: &mut Parser) { | |||
15 | while !p.at(EOF) && !p.at(R_ANGLE) { | 15 | while !p.at(EOF) && !p.at(R_ANGLE) { |
16 | match p.current() { | 16 | match p.current() { |
17 | LIFETIME => lifetime_param(p), | 17 | LIFETIME => lifetime_param(p), |
18 | IDENT => type_param(p), | 18 | IDENT | RAW_IDENT => type_param(p), |
19 | _ => p.err_and_bump("expected type parameter"), | 19 | _ => p.err_and_bump("expected type parameter"), |
20 | } | 20 | } |
21 | if !p.at(R_ANGLE) && !p.expect(COMMA) { | 21 | if !p.at(R_ANGLE) && !p.expect(COMMA) { |
@@ -37,7 +37,7 @@ fn lifetime_param(p: &mut Parser) { | |||
37 | } | 37 | } |
38 | 38 | ||
39 | fn type_param(p: &mut Parser) { | 39 | fn type_param(p: &mut Parser) { |
40 | assert!(p.at(IDENT)); | 40 | assert!(p.current().is_ident()); |
41 | let m = p.start(); | 41 | let m = p.start(); |
42 | name(p); | 42 | name(p); |
43 | if p.at(COLON) { | 43 | if p.at(COLON) { |
diff --git a/crates/ra_syntax/src/lexer.rs b/crates/ra_syntax/src/lexer.rs index c6acd095e..fab184a2d 100644 --- a/crates/ra_syntax/src/lexer.rs +++ b/crates/ra_syntax/src/lexer.rs | |||
@@ -190,19 +190,24 @@ fn next_token_inner(c: char, ptr: &mut Ptr) -> SyntaxKind { | |||
190 | } | 190 | } |
191 | 191 | ||
192 | fn scan_ident(c: char, ptr: &mut Ptr) -> SyntaxKind { | 192 | fn scan_ident(c: char, ptr: &mut Ptr) -> SyntaxKind { |
193 | let is_single_letter = match ptr.current() { | 193 | let is_raw = match (c, ptr.current()) { |
194 | None => true, | 194 | ('r', Some('#')) => { |
195 | Some(c) if !is_ident_continue(c) => true, | 195 | ptr.bump(); |
196 | true | ||
197 | } | ||
198 | ('_', Some(c)) if !is_ident_continue(c) => return UNDERSCORE, | ||
196 | _ => false, | 199 | _ => false, |
197 | }; | 200 | }; |
198 | if is_single_letter { | 201 | |
199 | return if c == '_' { UNDERSCORE } else { IDENT }; | ||
200 | } | ||
201 | ptr.bump_while(is_ident_continue); | 202 | ptr.bump_while(is_ident_continue); |
202 | if let Some(kind) = SyntaxKind::from_keyword(ptr.current_token_text()) { | 203 | |
204 | if is_raw { | ||
205 | RAW_IDENT | ||
206 | } else if let Some(kind) = SyntaxKind::from_keyword(ptr.current_token_text()) { | ||
203 | return kind; | 207 | return kind; |
208 | } else { | ||
209 | IDENT | ||
204 | } | 210 | } |
205 | IDENT | ||
206 | } | 211 | } |
207 | 212 | ||
208 | fn scan_literal_suffix(ptr: &mut Ptr) { | 213 | fn scan_literal_suffix(ptr: &mut Ptr) { |
diff --git a/crates/ra_syntax/src/lexer/strings.rs b/crates/ra_syntax/src/lexer/strings.rs index 0865b7f3b..5c1cf3e9c 100644 --- a/crates/ra_syntax/src/lexer/strings.rs +++ b/crates/ra_syntax/src/lexer/strings.rs | |||
@@ -5,7 +5,8 @@ use crate::lexer::ptr::Ptr; | |||
5 | pub(crate) fn is_string_literal_start(c: char, c1: Option<char>, c2: Option<char>) -> bool { | 5 | pub(crate) fn is_string_literal_start(c: char, c1: Option<char>, c2: Option<char>) -> bool { |
6 | match (c, c1, c2) { | 6 | match (c, c1, c2) { |
7 | ('r', Some('"'), _) | 7 | ('r', Some('"'), _) |
8 | | ('r', Some('#'), _) | 8 | | ('r', Some('#'), Some('"')) |
9 | | ('r', Some('#'), Some('#')) | ||
9 | | ('b', Some('"'), _) | 10 | | ('b', Some('"'), _) |
10 | | ('b', Some('\''), _) | 11 | | ('b', Some('\''), _) |
11 | | ('b', Some('r'), Some('"')) | 12 | | ('b', Some('r'), Some('"')) |
diff --git a/crates/ra_syntax/src/parser_api.rs b/crates/ra_syntax/src/parser_api.rs index 3148371c5..d795cbaf1 100644 --- a/crates/ra_syntax/src/parser_api.rs +++ b/crates/ra_syntax/src/parser_api.rs | |||
@@ -100,6 +100,14 @@ impl<'t> Parser<'t> { | |||
100 | true | 100 | true |
101 | } | 101 | } |
102 | 102 | ||
103 | /// Consume the next token matching one of the `kinds` | ||
104 | pub(crate) fn eat_one<'k, K>(&mut self, kinds: K) -> bool | ||
105 | where | ||
106 | K: IntoIterator<Item = &'k SyntaxKind> + 'k, | ||
107 | { | ||
108 | kinds.into_iter().map(|k| self.eat(*k)).any(|eaten| eaten) | ||
109 | } | ||
110 | |||
103 | /// Consume the next token if it is `kind` or emit an error | 111 | /// Consume the next token if it is `kind` or emit an error |
104 | /// otherwise. | 112 | /// otherwise. |
105 | pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool { | 113 | pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool { |
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs index 2f1de6b02..b38985bc8 100644 --- a/crates/ra_syntax/src/reparsing.rs +++ b/crates/ra_syntax/src/reparsing.rs | |||
@@ -25,7 +25,7 @@ fn reparse_leaf<'node>( | |||
25 | ) -> Option<(&'node SyntaxNode, GreenNode, Vec<SyntaxError>)> { | 25 | ) -> Option<(&'node SyntaxNode, GreenNode, Vec<SyntaxError>)> { |
26 | let node = algo::find_covering_node(node, edit.delete); | 26 | let node = algo::find_covering_node(node, edit.delete); |
27 | match node.kind() { | 27 | match node.kind() { |
28 | WHITESPACE | COMMENT | IDENT | STRING | RAW_STRING => { | 28 | WHITESPACE | COMMENT | IDENT | RAW_IDENT | STRING | RAW_STRING => { |
29 | let text = get_text_after_edit(node, &edit); | 29 | let text = get_text_after_edit(node, &edit); |
30 | let tokens = tokenize(&text); | 30 | let tokens = tokenize(&text); |
31 | let token = match tokens[..] { | 31 | let token = match tokens[..] { |
@@ -33,7 +33,7 @@ fn reparse_leaf<'node>( | |||
33 | _ => return None, | 33 | _ => return None, |
34 | }; | 34 | }; |
35 | 35 | ||
36 | if token.kind == IDENT && is_contextual_kw(&text) { | 36 | if token.kind.is_ident() && is_contextual_kw(&text) { |
37 | return None; | 37 | return None; |
38 | } | 38 | } |
39 | 39 | ||
diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs index 06faf7557..aa1ab3326 100644 --- a/crates/ra_syntax/src/syntax_kinds/generated.rs +++ b/crates/ra_syntax/src/syntax_kinds/generated.rs | |||
@@ -105,6 +105,7 @@ pub enum SyntaxKind { | |||
105 | UNION_KW, | 105 | UNION_KW, |
106 | ERROR, | 106 | ERROR, |
107 | IDENT, | 107 | IDENT, |
108 | RAW_IDENT, | ||
108 | UNDERSCORE, | 109 | UNDERSCORE, |
109 | WHITESPACE, | 110 | WHITESPACE, |
110 | INT_NUMBER, | 111 | INT_NUMBER, |
@@ -368,6 +369,7 @@ impl SyntaxKind { | |||
368 | UNION_KW => &SyntaxInfo { name: "UNION_KW" }, | 369 | UNION_KW => &SyntaxInfo { name: "UNION_KW" }, |
369 | ERROR => &SyntaxInfo { name: "ERROR" }, | 370 | ERROR => &SyntaxInfo { name: "ERROR" }, |
370 | IDENT => &SyntaxInfo { name: "IDENT" }, | 371 | IDENT => &SyntaxInfo { name: "IDENT" }, |
372 | RAW_IDENT => &SyntaxInfo { name: "RAW_IDENT" }, | ||
371 | UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" }, | 373 | UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" }, |
372 | WHITESPACE => &SyntaxInfo { name: "WHITESPACE" }, | 374 | WHITESPACE => &SyntaxInfo { name: "WHITESPACE" }, |
373 | INT_NUMBER => &SyntaxInfo { name: "INT_NUMBER" }, | 375 | INT_NUMBER => &SyntaxInfo { name: "INT_NUMBER" }, |
@@ -563,4 +565,12 @@ impl SyntaxKind { | |||
563 | }; | 565 | }; |
564 | Some(tok) | 566 | Some(tok) |
565 | } | 567 | } |
568 | |||
569 | pub(crate) fn is_ident(&self) -> bool { | ||
570 | match self { | ||
571 | | IDENT | ||
572 | | RAW_IDENT => true, | ||
573 | _ => false, | ||
574 | } | ||
575 | } | ||
566 | } | 576 | } |
diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs.tera b/crates/ra_syntax/src/syntax_kinds/generated.rs.tera index 21f9444b1..83787f820 100644 --- a/crates/ra_syntax/src/syntax_kinds/generated.rs.tera +++ b/crates/ra_syntax/src/syntax_kinds/generated.rs.tera | |||
@@ -74,4 +74,13 @@ impl SyntaxKind { | |||
74 | }; | 74 | }; |
75 | Some(tok) | 75 | Some(tok) |
76 | } | 76 | } |
77 | |||
78 | pub(crate) fn is_ident(&self) -> bool { | ||
79 | match self { | ||
80 | {%- for kind in ident_tokens %} | ||
81 | | {{kind}} | ||
82 | {%- endfor %} => true, | ||
83 | _ => false, | ||
84 | } | ||
85 | } | ||
77 | } | 86 | } |
diff --git a/crates/ra_syntax/src/yellow.rs b/crates/ra_syntax/src/yellow.rs index a7bfb80e2..48f01128b 100644 --- a/crates/ra_syntax/src/yellow.rs +++ b/crates/ra_syntax/src/yellow.rs | |||
@@ -207,7 +207,7 @@ impl<'a> Iterator for SyntaxNodeChildren<'a> { | |||
207 | fn has_short_text(kind: SyntaxKind) -> bool { | 207 | fn has_short_text(kind: SyntaxKind) -> bool { |
208 | use crate::SyntaxKind::*; | 208 | use crate::SyntaxKind::*; |
209 | match kind { | 209 | match kind { |
210 | IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true, | 210 | IDENT | RAW_IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true, |
211 | _ => false, | 211 | _ => false, |
212 | } | 212 | } |
213 | } | 213 | } |
diff --git a/crates/ra_syntax/tests/data/lexer/0016_raw_ident.rs b/crates/ra_syntax/tests/data/lexer/0016_raw_ident.rs new file mode 100644 index 000000000..b40a1b6a2 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0016_raw_ident.rs | |||
@@ -0,0 +1 @@ | |||
r#raw_ident | |||
diff --git a/crates/ra_syntax/tests/data/lexer/0016_raw_ident.txt b/crates/ra_syntax/tests/data/lexer/0016_raw_ident.txt new file mode 100644 index 000000000..28b9b208a --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0016_raw_ident.txt | |||
@@ -0,0 +1,2 @@ | |||
1 | RAW_IDENT 11 "r#raw_ident" | ||
2 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0039_raw_fn_item.rs b/crates/ra_syntax/tests/data/parser/ok/0039_raw_fn_item.rs new file mode 100644 index 000000000..8380d1e79 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0039_raw_fn_item.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | fn r#foo() { | ||
2 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0039_raw_fn_item.txt b/crates/ra_syntax/tests/data/parser/ok/0039_raw_fn_item.txt new file mode 100644 index 000000000..865a680f2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0039_raw_fn_item.txt | |||
@@ -0,0 +1,15 @@ | |||
1 | SOURCE_FILE@[0; 15) | ||
2 | FN_DEF@[0; 14) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 8) | ||
6 | RAW_IDENT@[3; 8) "r#foo" | ||
7 | PARAM_LIST@[8; 10) | ||
8 | L_PAREN@[8; 9) | ||
9 | R_PAREN@[9; 10) | ||
10 | WHITESPACE@[10; 11) | ||
11 | BLOCK@[11; 14) | ||
12 | L_CURLY@[11; 12) | ||
13 | WHITESPACE@[12; 13) | ||
14 | R_CURLY@[13; 14) | ||
15 | WHITESPACE@[14; 15) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0040_raw_struct_item_field.rs b/crates/ra_syntax/tests/data/parser/ok/0040_raw_struct_item_field.rs new file mode 100644 index 000000000..098a60a72 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0040_raw_struct_item_field.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | struct S { | ||
2 | r#foo: u32 | ||
3 | } \ No newline at end of file | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0040_raw_struct_item_field.txt b/crates/ra_syntax/tests/data/parser/ok/0040_raw_struct_item_field.txt new file mode 100644 index 000000000..4e244cbc5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0040_raw_struct_item_field.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | SOURCE_FILE@[0; 27) | ||
2 | STRUCT_DEF@[0; 27) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | WHITESPACE@[8; 9) | ||
8 | NAMED_FIELD_DEF_LIST@[9; 27) | ||
9 | L_CURLY@[9; 10) | ||
10 | WHITESPACE@[10; 15) | ||
11 | NAMED_FIELD_DEF@[15; 25) | ||
12 | NAME@[15; 20) | ||
13 | RAW_IDENT@[15; 20) "r#foo" | ||
14 | COLON@[20; 21) | ||
15 | WHITESPACE@[21; 22) | ||
16 | PATH_TYPE@[22; 25) | ||
17 | PATH@[22; 25) | ||
18 | PATH_SEGMENT@[22; 25) | ||
19 | NAME_REF@[22; 25) | ||
20 | IDENT@[22; 25) "u32" | ||
21 | WHITESPACE@[25; 26) | ||
22 | R_CURLY@[26; 27) | ||