aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
authorGeoffry Song <[email protected]>2019-11-15 20:05:29 +0000
committerGeoffry Song <[email protected]>2019-11-15 20:05:29 +0000
commit5645c153e0379874d1f44ab149c3ec9257812692 (patch)
tree82739e158bc148307ac245f5b97c6e97a4d65c69 /crates/ra_syntax/src
parenta68aefdc463af054e7e98293c06b751c135911d5 (diff)
Attempt to implement typed accessors
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast.rs2
-rw-r--r--crates/ra_syntax/src/ast/expr_extensions.rs46
-rw-r--r--crates/ra_syntax/src/validation.rs8
3 files changed, 49 insertions, 7 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
18pub use self::{ 18pub 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)]
193pub enum RangeOp {
194 /// `..`
195 Exclusive,
196 /// `..=`
197 Inclusive,
198}
199
200impl 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
192impl ast::IndexExpr { 238impl 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
232fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec<SyntaxError>) { 232fn 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}