diff options
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r-- | crates/ra_syntax/src/ast/expr_extensions.rs | 77 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/extensions.rs | 60 | ||||
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 9 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/lexer.rs | 25 | ||||
-rw-r--r-- | crates/ra_syntax/src/parsing/reparsing.rs | 11 | ||||
-rw-r--r-- | crates/ra_syntax/src/syntax_text.rs | 65 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation.rs | 7 |
7 files changed, 128 insertions, 126 deletions
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs index 9484c3b9b..17763809d 100644 --- a/crates/ra_syntax/src/ast/expr_extensions.rs +++ b/crates/ra_syntax/src/ast/expr_extensions.rs | |||
@@ -3,7 +3,8 @@ | |||
3 | use crate::{ | 3 | use crate::{ |
4 | SyntaxToken, SyntaxElement, SmolStr, | 4 | SyntaxToken, SyntaxElement, SmolStr, |
5 | ast::{self, AstNode, AstChildren, children, child_opt}, | 5 | ast::{self, AstNode, AstChildren, children, child_opt}, |
6 | SyntaxKind::* | 6 | SyntaxKind::*, |
7 | T | ||
7 | }; | 8 | }; |
8 | 9 | ||
9 | #[derive(Debug, Clone, PartialEq, Eq)] | 10 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -34,7 +35,7 @@ impl ast::IfExpr { | |||
34 | 35 | ||
35 | impl ast::RefExpr { | 36 | impl ast::RefExpr { |
36 | pub fn is_mut(&self) -> bool { | 37 | pub fn is_mut(&self) -> bool { |
37 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | 38 | self.syntax().children_with_tokens().any(|n| n.kind() == T![mut]) |
38 | } | 39 | } |
39 | } | 40 | } |
40 | 41 | ||
@@ -51,9 +52,9 @@ pub enum PrefixOp { | |||
51 | impl ast::PrefixExpr { | 52 | impl ast::PrefixExpr { |
52 | pub fn op_kind(&self) -> Option<PrefixOp> { | 53 | pub fn op_kind(&self) -> Option<PrefixOp> { |
53 | match self.op_token()?.kind() { | 54 | match self.op_token()?.kind() { |
54 | STAR => Some(PrefixOp::Deref), | 55 | T![*] => Some(PrefixOp::Deref), |
55 | EXCL => Some(PrefixOp::Not), | 56 | T![!] => Some(PrefixOp::Not), |
56 | MINUS => Some(PrefixOp::Neg), | 57 | T![-] => Some(PrefixOp::Neg), |
57 | _ => None, | 58 | _ => None, |
58 | } | 59 | } |
59 | } | 60 | } |
@@ -133,37 +134,37 @@ impl ast::BinExpr { | |||
133 | fn op_details(&self) -> Option<(SyntaxToken, BinOp)> { | 134 | fn op_details(&self) -> Option<(SyntaxToken, BinOp)> { |
134 | self.syntax().children_with_tokens().filter_map(|it| it.as_token()).find_map(|c| { | 135 | self.syntax().children_with_tokens().filter_map(|it| it.as_token()).find_map(|c| { |
135 | match c.kind() { | 136 | match c.kind() { |
136 | PIPEPIPE => Some((c, BinOp::BooleanOr)), | 137 | T![||] => Some((c, BinOp::BooleanOr)), |
137 | AMPAMP => Some((c, BinOp::BooleanAnd)), | 138 | T![&&] => Some((c, BinOp::BooleanAnd)), |
138 | EQEQ => Some((c, BinOp::EqualityTest)), | 139 | T![==] => Some((c, BinOp::EqualityTest)), |
139 | NEQ => Some((c, BinOp::NegatedEqualityTest)), | 140 | T![!=] => Some((c, BinOp::NegatedEqualityTest)), |
140 | LTEQ => Some((c, BinOp::LesserEqualTest)), | 141 | T![<=] => Some((c, BinOp::LesserEqualTest)), |
141 | GTEQ => Some((c, BinOp::GreaterEqualTest)), | 142 | T![>=] => Some((c, BinOp::GreaterEqualTest)), |
142 | L_ANGLE => Some((c, BinOp::LesserTest)), | 143 | T![<] => Some((c, BinOp::LesserTest)), |
143 | R_ANGLE => Some((c, BinOp::GreaterTest)), | 144 | T![>] => Some((c, BinOp::GreaterTest)), |
144 | PLUS => Some((c, BinOp::Addition)), | 145 | T![+] => Some((c, BinOp::Addition)), |
145 | STAR => Some((c, BinOp::Multiplication)), | 146 | T![*] => Some((c, BinOp::Multiplication)), |
146 | MINUS => Some((c, BinOp::Subtraction)), | 147 | T![-] => Some((c, BinOp::Subtraction)), |
147 | SLASH => Some((c, BinOp::Division)), | 148 | T![/] => Some((c, BinOp::Division)), |
148 | PERCENT => Some((c, BinOp::Remainder)), | 149 | T![%] => Some((c, BinOp::Remainder)), |
149 | SHL => Some((c, BinOp::LeftShift)), | 150 | T![<<] => Some((c, BinOp::LeftShift)), |
150 | SHR => Some((c, BinOp::RightShift)), | 151 | T![>>] => Some((c, BinOp::RightShift)), |
151 | CARET => Some((c, BinOp::BitwiseXor)), | 152 | T![^] => Some((c, BinOp::BitwiseXor)), |
152 | PIPE => Some((c, BinOp::BitwiseOr)), | 153 | T![|] => Some((c, BinOp::BitwiseOr)), |
153 | AMP => Some((c, BinOp::BitwiseAnd)), | 154 | T![&] => Some((c, BinOp::BitwiseAnd)), |
154 | DOTDOT => Some((c, BinOp::RangeRightOpen)), | 155 | T![..] => Some((c, BinOp::RangeRightOpen)), |
155 | DOTDOTEQ => Some((c, BinOp::RangeRightClosed)), | 156 | T![..=] => Some((c, BinOp::RangeRightClosed)), |
156 | EQ => Some((c, BinOp::Assignment)), | 157 | T![=] => Some((c, BinOp::Assignment)), |
157 | PLUSEQ => Some((c, BinOp::AddAssign)), | 158 | T![+=] => Some((c, BinOp::AddAssign)), |
158 | SLASHEQ => Some((c, BinOp::DivAssign)), | 159 | T![/=] => Some((c, BinOp::DivAssign)), |
159 | STAREQ => Some((c, BinOp::MulAssign)), | 160 | T![*=] => Some((c, BinOp::MulAssign)), |
160 | PERCENTEQ => Some((c, BinOp::RemAssign)), | 161 | T![%=] => Some((c, BinOp::RemAssign)), |
161 | SHREQ => Some((c, BinOp::ShrAssign)), | 162 | T![>>=] => Some((c, BinOp::ShrAssign)), |
162 | SHLEQ => Some((c, BinOp::ShlAssign)), | 163 | T![<<=] => Some((c, BinOp::ShlAssign)), |
163 | MINUSEQ => Some((c, BinOp::SubAssign)), | 164 | T![-=] => Some((c, BinOp::SubAssign)), |
164 | PIPEEQ => Some((c, BinOp::BitOrAssign)), | 165 | T![|=] => Some((c, BinOp::BitOrAssign)), |
165 | AMPEQ => Some((c, BinOp::BitAndAssign)), | 166 | T![&=] => Some((c, BinOp::BitAndAssign)), |
166 | CARETEQ => Some((c, BinOp::BitXorAssign)), | 167 | T![^=] => Some((c, BinOp::BitXorAssign)), |
167 | _ => None, | 168 | _ => None, |
168 | } | 169 | } |
169 | }) | 170 | }) |
@@ -211,7 +212,7 @@ impl ast::ArrayExpr { | |||
211 | } | 212 | } |
212 | 213 | ||
213 | fn is_repeat(&self) -> bool { | 214 | fn is_repeat(&self) -> bool { |
214 | self.syntax().children_with_tokens().any(|it| it.kind() == SEMI) | 215 | self.syntax().children_with_tokens().any(|it| it.kind() == T![;]) |
215 | } | 216 | } |
216 | } | 217 | } |
217 | 218 | ||
@@ -258,7 +259,7 @@ impl ast::Literal { | |||
258 | LiteralKind::FloatNumber { suffix: suffix } | 259 | LiteralKind::FloatNumber { suffix: suffix } |
259 | } | 260 | } |
260 | STRING | RAW_STRING => LiteralKind::String, | 261 | STRING | RAW_STRING => LiteralKind::String, |
261 | TRUE_KW | FALSE_KW => LiteralKind::Bool, | 262 | T![true] | T![false] => LiteralKind::Bool, |
262 | BYTE_STRING | RAW_BYTE_STRING => LiteralKind::ByteString, | 263 | BYTE_STRING | RAW_BYTE_STRING => LiteralKind::ByteString, |
263 | CHAR => LiteralKind::Char, | 264 | CHAR => LiteralKind::Char, |
264 | BYTE => LiteralKind::Byte, | 265 | BYTE => LiteralKind::Byte, |
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index f3466c585..e4c99784c 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs | |||
@@ -3,7 +3,12 @@ | |||
3 | 3 | ||
4 | use itertools::Itertools; | 4 | use itertools::Itertools; |
5 | 5 | ||
6 | use crate::{SmolStr, SyntaxToken, ast::{self, AstNode, children, child_opt}, SyntaxKind::*, SyntaxElement}; | 6 | use crate::{ |
7 | SmolStr, SyntaxToken, | ||
8 | ast::{self, AstNode, children, child_opt}, | ||
9 | SyntaxKind::*, | ||
10 | SyntaxElement, T, | ||
11 | }; | ||
7 | use ra_parser::SyntaxKind; | 12 | use ra_parser::SyntaxKind; |
8 | 13 | ||
9 | impl ast::Name { | 14 | impl ast::Name { |
@@ -32,7 +37,7 @@ impl ast::Attr { | |||
32 | Some(prev) => prev, | 37 | Some(prev) => prev, |
33 | }; | 38 | }; |
34 | 39 | ||
35 | prev.kind() == EXCL | 40 | prev.kind() == T![!] |
36 | } | 41 | } |
37 | 42 | ||
38 | pub fn as_atom(&self) -> Option<SmolStr> { | 43 | pub fn as_atom(&self) -> Option<SmolStr> { |
@@ -102,9 +107,9 @@ impl ast::PathSegment { | |||
102 | PathSegmentKind::Name(name_ref) | 107 | PathSegmentKind::Name(name_ref) |
103 | } else { | 108 | } else { |
104 | match self.syntax().first_child_or_token()?.kind() { | 109 | match self.syntax().first_child_or_token()?.kind() { |
105 | SELF_KW => PathSegmentKind::SelfKw, | 110 | T![self] => PathSegmentKind::SelfKw, |
106 | SUPER_KW => PathSegmentKind::SuperKw, | 111 | T![super] => PathSegmentKind::SuperKw, |
107 | CRATE_KW => PathSegmentKind::CrateKw, | 112 | T![crate] => PathSegmentKind::CrateKw, |
108 | _ => return None, | 113 | _ => return None, |
109 | } | 114 | } |
110 | }; | 115 | }; |
@@ -113,7 +118,7 @@ impl ast::PathSegment { | |||
113 | 118 | ||
114 | pub fn has_colon_colon(&self) -> bool { | 119 | pub fn has_colon_colon(&self) -> bool { |
115 | match self.syntax.first_child_or_token().map(|s| s.kind()) { | 120 | match self.syntax.first_child_or_token().map(|s| s.kind()) { |
116 | Some(COLONCOLON) => true, | 121 | Some(T![::]) => true, |
117 | _ => false, | 122 | _ => false, |
118 | } | 123 | } |
119 | } | 124 | } |
@@ -129,14 +134,14 @@ impl ast::Module { | |||
129 | pub fn has_semi(&self) -> bool { | 134 | pub fn has_semi(&self) -> bool { |
130 | match self.syntax().last_child_or_token() { | 135 | match self.syntax().last_child_or_token() { |
131 | None => false, | 136 | None => false, |
132 | Some(node) => node.kind() == SEMI, | 137 | Some(node) => node.kind() == T![;], |
133 | } | 138 | } |
134 | } | 139 | } |
135 | } | 140 | } |
136 | 141 | ||
137 | impl ast::UseTree { | 142 | impl ast::UseTree { |
138 | pub fn has_star(&self) -> bool { | 143 | pub fn has_star(&self) -> bool { |
139 | self.syntax().children_with_tokens().any(|it| it.kind() == STAR) | 144 | self.syntax().children_with_tokens().any(|it| it.kind() == T![*]) |
140 | } | 145 | } |
141 | } | 146 | } |
142 | 147 | ||
@@ -172,7 +177,7 @@ impl ast::ImplBlock { | |||
172 | } | 177 | } |
173 | 178 | ||
174 | pub fn is_negative(&self) -> bool { | 179 | pub fn is_negative(&self) -> bool { |
175 | self.syntax().children_with_tokens().any(|t| t.kind() == EXCL) | 180 | self.syntax().children_with_tokens().any(|t| t.kind() == T![!]) |
176 | } | 181 | } |
177 | } | 182 | } |
178 | 183 | ||
@@ -196,6 +201,17 @@ impl StructKind<'_> { | |||
196 | } | 201 | } |
197 | 202 | ||
198 | impl ast::StructDef { | 203 | impl ast::StructDef { |
204 | pub fn is_union(&self) -> bool { | ||
205 | for child in self.syntax().children_with_tokens() { | ||
206 | match child.kind() { | ||
207 | T![struct] => return false, | ||
208 | T![union] => return true, | ||
209 | _ => (), | ||
210 | } | ||
211 | } | ||
212 | false | ||
213 | } | ||
214 | |||
199 | pub fn kind(&self) -> StructKind { | 215 | pub fn kind(&self) -> StructKind { |
200 | StructKind::from_node(self) | 216 | StructKind::from_node(self) |
201 | } | 217 | } |
@@ -219,7 +235,7 @@ impl ast::FnDef { | |||
219 | self.syntax() | 235 | self.syntax() |
220 | .last_child_or_token() | 236 | .last_child_or_token() |
221 | .and_then(|it| it.as_token()) | 237 | .and_then(|it| it.as_token()) |
222 | .filter(|it| it.kind() == SEMI) | 238 | .filter(|it| it.kind() == T![;]) |
223 | } | 239 | } |
224 | } | 240 | } |
225 | 241 | ||
@@ -227,7 +243,7 @@ impl ast::LetStmt { | |||
227 | pub fn has_semi(&self) -> bool { | 243 | pub fn has_semi(&self) -> bool { |
228 | match self.syntax().last_child_or_token() { | 244 | match self.syntax().last_child_or_token() { |
229 | None => false, | 245 | None => false, |
230 | Some(node) => node.kind() == SEMI, | 246 | Some(node) => node.kind() == T![;], |
231 | } | 247 | } |
232 | } | 248 | } |
233 | } | 249 | } |
@@ -236,7 +252,7 @@ impl ast::ExprStmt { | |||
236 | pub fn has_semi(&self) -> bool { | 252 | pub fn has_semi(&self) -> bool { |
237 | match self.syntax().last_child_or_token() { | 253 | match self.syntax().last_child_or_token() { |
238 | None => false, | 254 | None => false, |
239 | Some(node) => node.kind() == SEMI, | 255 | Some(node) => node.kind() == T![;], |
240 | } | 256 | } |
241 | } | 257 | } |
242 | } | 258 | } |
@@ -270,29 +286,29 @@ impl ast::FieldExpr { | |||
270 | 286 | ||
271 | impl ast::RefPat { | 287 | impl ast::RefPat { |
272 | pub fn is_mut(&self) -> bool { | 288 | pub fn is_mut(&self) -> bool { |
273 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | 289 | self.syntax().children_with_tokens().any(|n| n.kind() == T![mut]) |
274 | } | 290 | } |
275 | } | 291 | } |
276 | 292 | ||
277 | impl ast::BindPat { | 293 | impl ast::BindPat { |
278 | pub fn is_mutable(&self) -> bool { | 294 | pub fn is_mutable(&self) -> bool { |
279 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | 295 | self.syntax().children_with_tokens().any(|n| n.kind() == T![mut]) |
280 | } | 296 | } |
281 | 297 | ||
282 | pub fn is_ref(&self) -> bool { | 298 | pub fn is_ref(&self) -> bool { |
283 | self.syntax().children_with_tokens().any(|n| n.kind() == REF_KW) | 299 | self.syntax().children_with_tokens().any(|n| n.kind() == T![ref]) |
284 | } | 300 | } |
285 | } | 301 | } |
286 | 302 | ||
287 | impl ast::PointerType { | 303 | impl ast::PointerType { |
288 | pub fn is_mut(&self) -> bool { | 304 | pub fn is_mut(&self) -> bool { |
289 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | 305 | self.syntax().children_with_tokens().any(|n| n.kind() == T![mut]) |
290 | } | 306 | } |
291 | } | 307 | } |
292 | 308 | ||
293 | impl ast::ReferenceType { | 309 | impl ast::ReferenceType { |
294 | pub fn is_mut(&self) -> bool { | 310 | pub fn is_mut(&self) -> bool { |
295 | self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) | 311 | self.syntax().children_with_tokens().any(|n| n.kind() == T![mut]) |
296 | } | 312 | } |
297 | } | 313 | } |
298 | 314 | ||
@@ -311,19 +327,19 @@ impl ast::SelfParam { | |||
311 | self.syntax() | 327 | self.syntax() |
312 | .children_with_tokens() | 328 | .children_with_tokens() |
313 | .filter_map(|it| it.as_token()) | 329 | .filter_map(|it| it.as_token()) |
314 | .find(|it| it.kind() == SELF_KW) | 330 | .find(|it| it.kind() == T![self]) |
315 | .expect("invalid tree: self param must have self") | 331 | .expect("invalid tree: self param must have self") |
316 | } | 332 | } |
317 | 333 | ||
318 | pub fn kind(&self) -> SelfParamKind { | 334 | pub fn kind(&self) -> SelfParamKind { |
319 | let borrowed = self.syntax().children_with_tokens().any(|n| n.kind() == AMP); | 335 | let borrowed = self.syntax().children_with_tokens().any(|n| n.kind() == T![&]); |
320 | if borrowed { | 336 | if borrowed { |
321 | // check for a `mut` coming after the & -- `mut &self` != `&mut self` | 337 | // check for a `mut` coming after the & -- `mut &self` != `&mut self` |
322 | if self | 338 | if self |
323 | .syntax() | 339 | .syntax() |
324 | .children_with_tokens() | 340 | .children_with_tokens() |
325 | .skip_while(|n| n.kind() != AMP) | 341 | .skip_while(|n| n.kind() != T![&]) |
326 | .any(|n| n.kind() == MUT_KW) | 342 | .any(|n| n.kind() == T![mut]) |
327 | { | 343 | { |
328 | SelfParamKind::MutRef | 344 | SelfParamKind::MutRef |
329 | } else { | 345 | } else { |
@@ -355,6 +371,6 @@ impl ast::WherePred { | |||
355 | 371 | ||
356 | impl ast::TraitDef { | 372 | impl ast::TraitDef { |
357 | pub fn is_auto(&self) -> bool { | 373 | pub fn is_auto(&self) -> bool { |
358 | self.syntax().children_with_tokens().any(|t| t.kind() == AUTO_KW) | 374 | self.syntax().children_with_tokens().any(|t| t.kind() == T![auto]) |
359 | } | 375 | } |
360 | } | 376 | } |
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 65c65d6aa..0ceabc203 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -179,10 +179,7 @@ fn api_walkthrough() { | |||
179 | 179 | ||
180 | // There's a bunch of traversal methods on `SyntaxNode`: | 180 | // There's a bunch of traversal methods on `SyntaxNode`: |
181 | assert_eq!(expr_syntax.parent(), Some(block.syntax())); | 181 | assert_eq!(expr_syntax.parent(), Some(block.syntax())); |
182 | assert_eq!( | 182 | assert_eq!(block.syntax().first_child_or_token().map(|it| it.kind()), Some(T!['{'])); |
183 | block.syntax().first_child_or_token().map(|it| it.kind()), | ||
184 | Some(SyntaxKind::L_CURLY) | ||
185 | ); | ||
186 | assert_eq!( | 183 | assert_eq!( |
187 | expr_syntax.next_sibling_or_token().map(|it| it.kind()), | 184 | expr_syntax.next_sibling_or_token().map(|it| it.kind()), |
188 | Some(SyntaxKind::WHITESPACE) | 185 | Some(SyntaxKind::WHITESPACE) |
@@ -191,9 +188,7 @@ fn api_walkthrough() { | |||
191 | // As well as some iterator helpers: | 188 | // As well as some iterator helpers: |
192 | let f = expr_syntax.ancestors().find_map(ast::FnDef::cast); | 189 | let f = expr_syntax.ancestors().find_map(ast::FnDef::cast); |
193 | assert_eq!(f, Some(&*func)); | 190 | assert_eq!(f, Some(&*func)); |
194 | assert!(expr_syntax | 191 | assert!(expr_syntax.siblings_with_tokens(Direction::Next).any(|it| it.kind() == T!['}'])); |
195 | .siblings_with_tokens(Direction::Next) | ||
196 | .any(|it| it.kind() == SyntaxKind::R_CURLY)); | ||
197 | assert_eq!( | 192 | assert_eq!( |
198 | expr_syntax.descendants_with_tokens().count(), | 193 | expr_syntax.descendants_with_tokens().count(), |
199 | 8, // 5 tokens `1`, ` `, `+`, ` `, `!` | 194 | 8, // 5 tokens `1`, ` `, `+`, ` `, `!` |
diff --git a/crates/ra_syntax/src/parsing/lexer.rs b/crates/ra_syntax/src/parsing/lexer.rs index a3791b503..6eb96f03d 100644 --- a/crates/ra_syntax/src/parsing/lexer.rs +++ b/crates/ra_syntax/src/parsing/lexer.rs | |||
@@ -7,6 +7,7 @@ mod strings; | |||
7 | use crate::{ | 7 | use crate::{ |
8 | SyntaxKind::{self, *}, | 8 | SyntaxKind::{self, *}, |
9 | TextUnit, | 9 | TextUnit, |
10 | T, | ||
10 | }; | 11 | }; |
11 | 12 | ||
12 | use self::{ | 13 | use self::{ |
@@ -90,16 +91,16 @@ fn next_token_inner(c: char, ptr: &mut Ptr) -> SyntaxKind { | |||
90 | match c { | 91 | match c { |
91 | // Possiblily multi-byte tokens, | 92 | // Possiblily multi-byte tokens, |
92 | // but we only produce single byte token now | 93 | // but we only produce single byte token now |
93 | // DOTDOTDOT, DOTDOT, DOTDOTEQ, DOT | 94 | // T![...], T![..], T![..=], T![.] |
94 | '.' => return DOT, | 95 | '.' => return T![.], |
95 | // COLONCOLON COLON | 96 | // T![::] T![:] |
96 | ':' => return COLON, | 97 | ':' => return T![:], |
97 | // EQEQ FATARROW EQ | 98 | // T![==] FATARROW T![=] |
98 | '=' => return EQ, | 99 | '=' => return T![=], |
99 | // NEQ EXCL | 100 | // T![!=] T![!] |
100 | '!' => return EXCL, | 101 | '!' => return T![!], |
101 | // THIN_ARROW MINUS | 102 | // T![->] T![-] |
102 | '-' => return MINUS, | 103 | '-' => return T![-], |
103 | 104 | ||
104 | // If the character is an ident start not followed by another single | 105 | // If the character is an ident start not followed by another single |
105 | // quote, then this is a lifetime name: | 106 | // quote, then this is a lifetime name: |
@@ -148,8 +149,8 @@ fn scan_ident(c: char, ptr: &mut Ptr) -> SyntaxKind { | |||
148 | ptr.bump(); | 149 | ptr.bump(); |
149 | true | 150 | true |
150 | } | 151 | } |
151 | ('_', None) => return UNDERSCORE, | 152 | ('_', None) => return T![_], |
152 | ('_', Some(c)) if !is_ident_continue(c) => return UNDERSCORE, | 153 | ('_', Some(c)) if !is_ident_continue(c) => return T![_], |
153 | _ => false, | 154 | _ => false, |
154 | }; | 155 | }; |
155 | ptr.bump_while(is_ident_continue); | 156 | ptr.bump_while(is_ident_continue); |
diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs index 434f850d1..6de02a15a 100644 --- a/crates/ra_syntax/src/parsing/reparsing.rs +++ b/crates/ra_syntax/src/parsing/reparsing.rs | |||
@@ -17,7 +17,8 @@ use crate::{ | |||
17 | text_token_source::TextTokenSource, | 17 | text_token_source::TextTokenSource, |
18 | text_tree_sink::TextTreeSink, | 18 | text_tree_sink::TextTreeSink, |
19 | lexer::{tokenize, Token}, | 19 | lexer::{tokenize, Token}, |
20 | } | 20 | }, |
21 | T, | ||
21 | }; | 22 | }; |
22 | 23 | ||
23 | pub(crate) fn incremental_reparse( | 24 | pub(crate) fn incremental_reparse( |
@@ -122,16 +123,16 @@ fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(&SyntaxN | |||
122 | 123 | ||
123 | fn is_balanced(tokens: &[Token]) -> bool { | 124 | fn is_balanced(tokens: &[Token]) -> bool { |
124 | if tokens.is_empty() | 125 | if tokens.is_empty() |
125 | || tokens.first().unwrap().kind != L_CURLY | 126 | || tokens.first().unwrap().kind != T!['{'] |
126 | || tokens.last().unwrap().kind != R_CURLY | 127 | || tokens.last().unwrap().kind != T!['}'] |
127 | { | 128 | { |
128 | return false; | 129 | return false; |
129 | } | 130 | } |
130 | let mut balance = 0usize; | 131 | let mut balance = 0usize; |
131 | for t in &tokens[1..tokens.len() - 1] { | 132 | for t in &tokens[1..tokens.len() - 1] { |
132 | match t.kind { | 133 | match t.kind { |
133 | L_CURLY => balance += 1, | 134 | T!['{'] => balance += 1, |
134 | R_CURLY => { | 135 | T!['}'] => { |
135 | balance = match balance.checked_sub(1) { | 136 | balance = match balance.checked_sub(1) { |
136 | Some(b) => b, | 137 | Some(b) => b, |
137 | None => return false, | 138 | None => return false, |
diff --git a/crates/ra_syntax/src/syntax_text.rs b/crates/ra_syntax/src/syntax_text.rs index 6bb2ff461..b013164c4 100644 --- a/crates/ra_syntax/src/syntax_text.rs +++ b/crates/ra_syntax/src/syntax_text.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::{fmt, ops}; | 1 | use std::{fmt, ops::{self, Bound}}; |
2 | 2 | ||
3 | use crate::{SyntaxNode, TextRange, TextUnit, SyntaxElement}; | 3 | use crate::{SyntaxNode, TextRange, TextUnit, SyntaxElement}; |
4 | 4 | ||
@@ -54,10 +54,31 @@ impl<'a> SyntaxText<'a> { | |||
54 | self.range.len() | 54 | self.range.len() |
55 | } | 55 | } |
56 | 56 | ||
57 | pub fn slice(&self, range: impl SyntaxTextSlice) -> SyntaxText<'a> { | 57 | /// NB, the offsets here are absolute, and this probably doesn't make sense! |
58 | let range = range.restrict(self.range).unwrap_or_else(|| { | 58 | pub fn slice(&self, range: impl ops::RangeBounds<TextUnit>) -> SyntaxText<'a> { |
59 | panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range) | 59 | let start = match range.start_bound() { |
60 | }); | 60 | Bound::Included(b) => *b, |
61 | Bound::Excluded(b) => *b + TextUnit::from(1u32), | ||
62 | Bound::Unbounded => self.range.start(), | ||
63 | }; | ||
64 | let end = match range.end_bound() { | ||
65 | Bound::Included(b) => *b + TextUnit::from(1u32), | ||
66 | Bound::Excluded(b) => *b, | ||
67 | Bound::Unbounded => self.range.end(), | ||
68 | }; | ||
69 | assert!( | ||
70 | start <= end, | ||
71 | "invalid slice, range: {:?}, slice: {:?}", | ||
72 | self.range, | ||
73 | (range.start_bound(), range.end_bound()), | ||
74 | ); | ||
75 | let range = TextRange::from_to(start, end); | ||
76 | assert!( | ||
77 | range.is_subrange(&self.range), | ||
78 | "invalid slice, range: {:?}, slice: {:?}", | ||
79 | self.range, | ||
80 | range, | ||
81 | ); | ||
61 | SyntaxText { node: self.node, range } | 82 | SyntaxText { node: self.node, range } |
62 | } | 83 | } |
63 | 84 | ||
@@ -88,40 +109,6 @@ impl<'a> fmt::Display for SyntaxText<'a> { | |||
88 | } | 109 | } |
89 | } | 110 | } |
90 | 111 | ||
91 | pub trait SyntaxTextSlice: fmt::Debug { | ||
92 | fn restrict(&self, range: TextRange) -> Option<TextRange>; | ||
93 | } | ||
94 | |||
95 | impl SyntaxTextSlice for TextRange { | ||
96 | fn restrict(&self, range: TextRange) -> Option<TextRange> { | ||
97 | self.intersection(&range) | ||
98 | } | ||
99 | } | ||
100 | |||
101 | impl SyntaxTextSlice for ops::RangeTo<TextUnit> { | ||
102 | fn restrict(&self, range: TextRange) -> Option<TextRange> { | ||
103 | if !range.contains_inclusive(self.end) { | ||
104 | return None; | ||
105 | } | ||
106 | Some(TextRange::from_to(range.start(), self.end)) | ||
107 | } | ||
108 | } | ||
109 | |||
110 | impl SyntaxTextSlice for ops::RangeFrom<TextUnit> { | ||
111 | fn restrict(&self, range: TextRange) -> Option<TextRange> { | ||
112 | if !range.contains_inclusive(self.start) { | ||
113 | return None; | ||
114 | } | ||
115 | Some(TextRange::from_to(self.start, range.end())) | ||
116 | } | ||
117 | } | ||
118 | |||
119 | impl SyntaxTextSlice for ops::Range<TextUnit> { | ||
120 | fn restrict(&self, range: TextRange) -> Option<TextRange> { | ||
121 | TextRange::from_to(self.start, self.end).restrict(range) | ||
122 | } | ||
123 | } | ||
124 | |||
125 | impl From<SyntaxText<'_>> for String { | 112 | impl From<SyntaxText<'_>> for String { |
126 | fn from(text: SyntaxText) -> String { | 113 | fn from(text: SyntaxText) -> String { |
127 | text.to_string() | 114 | text.to_string() |
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index 11a1fb4a7..b53900a4b 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -5,9 +5,10 @@ mod field_expr; | |||
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | SourceFile, SyntaxError, AstNode, SyntaxNode, TextUnit, | 7 | SourceFile, SyntaxError, AstNode, SyntaxNode, TextUnit, |
8 | SyntaxKind::{L_CURLY, R_CURLY, BYTE, BYTE_STRING, STRING, CHAR}, | 8 | SyntaxKind::{BYTE, BYTE_STRING, STRING, CHAR}, |
9 | ast, | 9 | ast, |
10 | algo::visit::{visitor_ctx, VisitorCtx}, | 10 | algo::visit::{visitor_ctx, VisitorCtx}, |
11 | T, | ||
11 | }; | 12 | }; |
12 | 13 | ||
13 | pub(crate) use unescape::EscapeError; | 14 | pub(crate) use unescape::EscapeError; |
@@ -83,8 +84,8 @@ pub(crate) fn validate_block_structure(root: &SyntaxNode) { | |||
83 | let mut stack = Vec::new(); | 84 | let mut stack = Vec::new(); |
84 | for node in root.descendants() { | 85 | for node in root.descendants() { |
85 | match node.kind() { | 86 | match node.kind() { |
86 | L_CURLY => stack.push(node), | 87 | T!['{'] => stack.push(node), |
87 | R_CURLY => { | 88 | T!['}'] => { |
88 | if let Some(pair) = stack.pop() { | 89 | if let Some(pair) = stack.pop() { |
89 | assert_eq!( | 90 | assert_eq!( |
90 | node.parent(), | 91 | node.parent(), |