aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
authorrobojumper <[email protected]>2019-04-05 21:34:45 +0100
committerrobojumper <[email protected]>2019-04-06 00:07:35 +0100
commitca40ca93a55ffa08d3e699fc877e7e189b526c66 (patch)
tree8b56a9250db5c713da3fc14758c0583bbb029638 /crates/ra_syntax/src
parent0372eca5b2e6dade5132a08db46992ca73a25188 (diff)
Parse and infer tuple indices
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast.rs2
-rw-r--r--crates/ra_syntax/src/ast/extensions.rs34
-rw-r--r--crates/ra_syntax/src/syntax_error.rs4
-rw-r--r--crates/ra_syntax/src/validation.rs2
-rw-r--r--crates/ra_syntax/src/validation/field_expr.rs12
5 files changed, 48 insertions, 6 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 9f5c41b0c..a06a6375d 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -17,7 +17,7 @@ pub use self::{
17 generated::*, 17 generated::*,
18 traits::*, 18 traits::*,
19 tokens::*, 19 tokens::*,
20 extensions::{PathSegmentKind, StructKind, SelfParamKind}, 20 extensions::{PathSegmentKind, StructKind, FieldKind, SelfParamKind},
21 expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind}, 21 expr_extensions::{ElseBranch, PrefixOp, BinOp, LiteralKind},
22}; 22};
23 23
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index aec57c380..ca33b43e7 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -3,11 +3,8 @@
3 3
4use itertools::Itertools; 4use itertools::Itertools;
5 5
6use crate::{ 6use crate::{SmolStr, SyntaxToken, ast::{self, AstNode, children, child_opt}, SyntaxKind::*, SyntaxElement};
7 SmolStr, SyntaxToken, 7use ra_parser::SyntaxKind;
8 ast::{self, AstNode, children, child_opt},
9 SyntaxKind::*,
10};
11 8
12impl ast::Name { 9impl ast::Name {
13 pub fn text(&self) -> &SmolStr { 10 pub fn text(&self) -> &SmolStr {
@@ -217,6 +214,33 @@ impl ast::ExprStmt {
217 } 214 }
218} 215}
219 216
217#[derive(Debug, Clone, PartialEq, Eq)]
218pub enum FieldKind<'a> {
219 Name(&'a ast::NameRef),
220 Index(SyntaxToken<'a>),
221}
222
223impl ast::FieldExpr {
224 pub fn index_token(&self) -> Option<SyntaxToken> {
225 self.syntax
226 .children_with_tokens()
227 // FIXME: Accepting floats here to reject them in validation later
228 .find(|c| c.kind() == SyntaxKind::INT_NUMBER || c.kind() == SyntaxKind::FLOAT_NUMBER)
229 .as_ref()
230 .and_then(SyntaxElement::as_token)
231 }
232
233 pub fn field_access(&self) -> Option<FieldKind> {
234 if let Some(nr) = self.name_ref() {
235 Some(FieldKind::Name(nr))
236 } else if let Some(tok) = self.index_token() {
237 Some(FieldKind::Index(tok))
238 } else {
239 None
240 }
241 }
242}
243
220impl ast::RefPat { 244impl ast::RefPat {
221 pub fn is_mut(&self) -> bool { 245 pub fn is_mut(&self) -> bool {
222 self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW) 246 self.syntax().children_with_tokens().any(|n| n.kind() == MUT_KW)
diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs
index 4b8c22a57..4198eefdb 100644
--- a/crates/ra_syntax/src/syntax_error.rs
+++ b/crates/ra_syntax/src/syntax_error.rs
@@ -95,6 +95,7 @@ pub enum SyntaxErrorKind {
95 InvalidSuffix, 95 InvalidSuffix,
96 InvalidBlockAttr, 96 InvalidBlockAttr,
97 InvalidMatchInnerAttr, 97 InvalidMatchInnerAttr,
98 InvalidTupleIndexFormat,
98} 99}
99 100
100impl fmt::Display for SyntaxErrorKind { 101impl fmt::Display for SyntaxErrorKind {
@@ -139,6 +140,9 @@ impl fmt::Display for SyntaxErrorKind {
139 InvalidMatchInnerAttr => { 140 InvalidMatchInnerAttr => {
140 write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression") 141 write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression")
141 } 142 }
143 InvalidTupleIndexFormat => {
144 write!(f, "Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix")
145 }
142 ParseError(msg) => write!(f, "{}", msg.0), 146 ParseError(msg) => write!(f, "{}", msg.0),
143 } 147 }
144 } 148 }
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs
index fc534df83..c2f545173 100644
--- a/crates/ra_syntax/src/validation.rs
+++ b/crates/ra_syntax/src/validation.rs
@@ -3,6 +3,7 @@ mod byte_string;
3mod char; 3mod char;
4mod string; 4mod string;
5mod block; 5mod block;
6mod field_expr;
6 7
7use crate::{ 8use crate::{
8 SourceFile, SyntaxError, AstNode, SyntaxNode, 9 SourceFile, SyntaxError, AstNode, SyntaxNode,
@@ -17,6 +18,7 @@ pub(crate) fn validate(file: &SourceFile) -> Vec<SyntaxError> {
17 let _ = visitor_ctx(&mut errors) 18 let _ = visitor_ctx(&mut errors)
18 .visit::<ast::Literal, _>(validate_literal) 19 .visit::<ast::Literal, _>(validate_literal)
19 .visit::<ast::Block, _>(block::validate_block_node) 20 .visit::<ast::Block, _>(block::validate_block_node)
21 .visit::<ast::FieldExpr, _>(field_expr::validate_field_expr_node)
20 .accept(node); 22 .accept(node);
21 } 23 }
22 errors 24 errors
diff --git a/crates/ra_syntax/src/validation/field_expr.rs b/crates/ra_syntax/src/validation/field_expr.rs
new file mode 100644
index 000000000..2b405062e
--- /dev/null
+++ b/crates/ra_syntax/src/validation/field_expr.rs
@@ -0,0 +1,12 @@
1use crate::{ast::{self, FieldKind},
2 SyntaxError,
3 SyntaxErrorKind::*,
4};
5
6pub(crate) fn validate_field_expr_node(node: &ast::FieldExpr, errors: &mut Vec<SyntaxError>) {
7 if let Some(FieldKind::Index(idx)) = node.field_access() {
8 if idx.text().chars().any(|c| c < '0' || c > '9') {
9 errors.push(SyntaxError::new(InvalidTupleIndexFormat, idx.range()));
10 }
11 }
12}