diff options
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 2 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/expr_extensions.rs | 46 | ||||
-rw-r--r-- | crates/ra_syntax/src/validation.rs | 8 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt | 2 |
4 files changed, 50 insertions, 8 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 1ec9881b9..277532a8c 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -16,7 +16,7 @@ use crate::{ | |||
16 | }; | 16 | }; |
17 | 17 | ||
18 | pub use self::{ | 18 | pub use self::{ |
19 | expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp}, | 19 | expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp}, |
20 | extensions::{FieldKind, PathSegmentKind, SelfParamKind, StructKind, TypeBoundKind}, | 20 | extensions::{FieldKind, PathSegmentKind, SelfParamKind, StructKind, TypeBoundKind}, |
21 | generated::*, | 21 | generated::*, |
22 | tokens::*, | 22 | tokens::*, |
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs index 25dbd0bed..7c53aa934 100644 --- a/crates/ra_syntax/src/ast/expr_extensions.rs +++ b/crates/ra_syntax/src/ast/expr_extensions.rs | |||
@@ -189,6 +189,52 @@ impl ast::BinExpr { | |||
189 | } | 189 | } |
190 | } | 190 | } |
191 | 191 | ||
192 | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||
193 | pub enum RangeOp { | ||
194 | /// `..` | ||
195 | Exclusive, | ||
196 | /// `..=` | ||
197 | Inclusive, | ||
198 | } | ||
199 | |||
200 | impl ast::RangeExpr { | ||
201 | fn op_details(&self) -> Option<(usize, SyntaxToken, RangeOp)> { | ||
202 | self.syntax().children_with_tokens().enumerate().find_map(|(ix, child)| { | ||
203 | let token = child.into_token()?; | ||
204 | let bin_op = match token.kind() { | ||
205 | T![..] => RangeOp::Exclusive, | ||
206 | T![..=] => RangeOp::Inclusive, | ||
207 | _ => return None, | ||
208 | }; | ||
209 | Some((ix, token, bin_op)) | ||
210 | }) | ||
211 | } | ||
212 | |||
213 | pub fn op_kind(&self) -> Option<RangeOp> { | ||
214 | self.op_details().map(|t| t.2) | ||
215 | } | ||
216 | |||
217 | pub fn op_token(&self) -> Option<SyntaxToken> { | ||
218 | self.op_details().map(|t| t.1) | ||
219 | } | ||
220 | |||
221 | pub fn start(&self) -> Option<ast::Expr> { | ||
222 | let op_ix = self.op_details()?.0; | ||
223 | self.syntax() | ||
224 | .children_with_tokens() | ||
225 | .take(op_ix) | ||
226 | .find_map(|it| ast::Expr::cast(it.into_node()?)) | ||
227 | } | ||
228 | |||
229 | pub fn end(&self) -> Option<ast::Expr> { | ||
230 | let op_ix = self.op_details()?.0; | ||
231 | self.syntax() | ||
232 | .children_with_tokens() | ||
233 | .skip(op_ix + 1) | ||
234 | .find_map(|it| ast::Expr::cast(it.into_node()?)) | ||
235 | } | ||
236 | } | ||
237 | |||
192 | impl ast::IndexExpr { | 238 | impl ast::IndexExpr { |
193 | pub fn base(&self) -> Option<ast::Expr> { | 239 | pub fn base(&self) -> Option<ast::Expr> { |
194 | children(self).nth(0) | 240 | children(self).nth(0) |
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index e01333e23..222ac15f8 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -230,14 +230,10 @@ fn validate_visibility(vis: ast::Visibility, errors: &mut Vec<SyntaxError>) { | |||
230 | } | 230 | } |
231 | 231 | ||
232 | fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec<SyntaxError>) { | 232 | fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec<SyntaxError>) { |
233 | let last_child = match expr.syntax().last_child_or_token() { | 233 | if expr.op_kind() == Some(ast::RangeOp::Inclusive) && expr.end().is_none() { |
234 | Some(it) => it, | ||
235 | None => return, | ||
236 | }; | ||
237 | if last_child.kind() == T![..=] { | ||
238 | errors.push(SyntaxError::new( | 234 | errors.push(SyntaxError::new( |
239 | SyntaxErrorKind::InclusiveRangeMissingEnd, | 235 | SyntaxErrorKind::InclusiveRangeMissingEnd, |
240 | last_child.text_range(), | 236 | expr.syntax().text_range(), |
241 | )); | 237 | )); |
242 | } | 238 | } |
243 | } | 239 | } |
diff --git a/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt b/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt index 749d53609..3810b9680 100644 --- a/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt +++ b/crates/ra_syntax/test_data/parser/err/0038_endless_inclusive_range.txt | |||
@@ -26,5 +26,5 @@ SOURCE_FILE@[0; 33) | |||
26 | WHITESPACE@[30; 31) "\n" | 26 | WHITESPACE@[30; 31) "\n" |
27 | R_CURLY@[31; 32) "}" | 27 | R_CURLY@[31; 32) "}" |
28 | WHITESPACE@[32; 33) "\n" | 28 | WHITESPACE@[32; 33) "\n" |
29 | error [17; 20): An inclusive range must have an end expression | 29 | error [16; 20): An inclusive range must have an end expression |
30 | error [26; 29): An inclusive range must have an end expression | 30 | error [26; 29): An inclusive range must have an end expression |