diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-11-15 20:15:29 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-11-15 20:15:29 +0000 |
commit | 86469d4195e7aeb93ae420d0c073593bfccc97f0 (patch) | |
tree | a2fd2d9a7be1b3310b842020c489197ebf2683c3 /crates/ra_syntax/src/ast/expr_extensions.rs | |
parent | 9c3e35df3327e4798867a005d8d22daca99825a1 (diff) | |
parent | 5645c153e0379874d1f44ab149c3ec9257812692 (diff) |
Merge #2252
2252: Fix parsing of "postfix" range expressions. r=matklad a=goffrie
Right now they are handled in `postfix_dot_expr`, but that doesn't allow it to
correctly handle precedence. Integrate it more tightly with the Pratt parser
instead.
Also includes a drive-by fix for parsing `match .. {}`.
Fixes #2242.
Co-authored-by: Geoffry Song <[email protected]>
Diffstat (limited to 'crates/ra_syntax/src/ast/expr_extensions.rs')
-rw-r--r-- | crates/ra_syntax/src/ast/expr_extensions.rs | 46 |
1 files changed, 46 insertions, 0 deletions
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) |