aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-04-06 00:24:11 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-04-06 00:24:11 +0100
commit990e74ba7c77485f914434ac6f09a40d1364634d (patch)
tree9e979e9ec084d717db9d4326df3a970db8d28947 /crates/ra_syntax
parent9d39b7bc42e6186b0fd6e1cec746d58c950f780e (diff)
parent2caa690ef6feba3f78354e715deea37983b149ac (diff)
Merge #1117
1117: [WIP] Tuple struct index inference r=matklad a=robojumper The first commit adds a helper struct `ast::FieldKind` to facilitate inference. The second commit adds a slightly modified test from #1109 while mentioning that there is a problem with how we're handling tuple indexing / floats. cc #1109 Co-authored-by: robojumper <[email protected]>
Diffstat (limited to 'crates/ra_syntax')
-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
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.txt51
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.rs1
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.txt27
9 files changed, 126 insertions, 12 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}
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.rs b/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.rs
new file mode 100644
index 000000000..30cc49138
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.rs
@@ -0,0 +1,5 @@
1fn foo() {
2 x.0.;
3 x.1i32;
4 x.0x01;
5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.txt b/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.txt
new file mode 100644
index 000000000..c111f60ea
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0010_bad_tuple_index_expr.txt
@@ -0,0 +1,51 @@
1SOURCE_FILE@[0; 47)
2 FN_DEF@[0; 46)
3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " "
11 BLOCK@[9; 46)
12 L_CURLY@[9; 10) "{"
13 WHITESPACE@[10; 15) "\n "
14 EXPR_STMT@[15; 20)
15 FIELD_EXPR@[15; 19)
16 PATH_EXPR@[15; 16)
17 PATH@[15; 16)
18 PATH_SEGMENT@[15; 16)
19 NAME_REF@[15; 16)
20 IDENT@[15; 16) "x"
21 DOT@[16; 17) "."
22 err: `Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix`
23 FLOAT_NUMBER@[17; 19) "0."
24 SEMI@[19; 20) ";"
25 WHITESPACE@[20; 25) "\n "
26 EXPR_STMT@[25; 32)
27 FIELD_EXPR@[25; 31)
28 PATH_EXPR@[25; 26)
29 PATH@[25; 26)
30 PATH_SEGMENT@[25; 26)
31 NAME_REF@[25; 26)
32 IDENT@[25; 26) "x"
33 DOT@[26; 27) "."
34 err: `Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix`
35 INT_NUMBER@[27; 31) "1i32"
36 SEMI@[31; 32) ";"
37 WHITESPACE@[32; 37) "\n "
38 EXPR_STMT@[37; 44)
39 FIELD_EXPR@[37; 43)
40 PATH_EXPR@[37; 38)
41 PATH@[37; 38)
42 PATH_SEGMENT@[37; 38)
43 NAME_REF@[37; 38)
44 IDENT@[37; 38) "x"
45 DOT@[38; 39) "."
46 err: `Tuple (struct) field access is only allowed through decimal integers with no underscores or suffix`
47 INT_NUMBER@[39; 43) "0x01"
48 SEMI@[43; 44) ";"
49 WHITESPACE@[44; 45) "\n"
50 R_CURLY@[45; 46) "}"
51 WHITESPACE@[46; 47) "\n"
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.rs
index 3e69538e5..b8da2ddc3 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.rs
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.rs
@@ -1,4 +1,5 @@
1fn foo() { 1fn foo() {
2 x.foo; 2 x.foo;
3 x.0.bar; 3 x.0.bar;
4 x.0();
4} 5}
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.txt
index a86702843..78054ec5a 100644
--- a/crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.txt
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0011_field_expr.txt
@@ -1,5 +1,5 @@
1SOURCE_FILE@[0; 37) 1SOURCE_FILE@[0; 48)
2 FN_DEF@[0; 36) 2 FN_DEF@[0; 47)
3 FN_KW@[0; 2) "fn" 3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " " 4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6) 5 NAME@[3; 6)
@@ -8,7 +8,7 @@ SOURCE_FILE@[0; 37)
8 L_PAREN@[6; 7) "(" 8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")" 9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " " 10 WHITESPACE@[8; 9) " "
11 BLOCK@[9; 36) 11 BLOCK@[9; 47)
12 L_CURLY@[9; 10) "{" 12 L_CURLY@[9; 10) "{"
13 WHITESPACE@[10; 15) "\n " 13 WHITESPACE@[10; 15) "\n "
14 EXPR_STMT@[15; 21) 14 EXPR_STMT@[15; 21)
@@ -37,6 +37,21 @@ SOURCE_FILE@[0; 37)
37 NAME_REF@[30; 33) 37 NAME_REF@[30; 33)
38 IDENT@[30; 33) "bar" 38 IDENT@[30; 33) "bar"
39 SEMI@[33; 34) ";" 39 SEMI@[33; 34) ";"
40 WHITESPACE@[34; 35) "\n" 40 WHITESPACE@[34; 39) "\n "
41 R_CURLY@[35; 36) "}" 41 EXPR_STMT@[39; 45)
42 WHITESPACE@[36; 37) "\n" 42 CALL_EXPR@[39; 44)
43 FIELD_EXPR@[39; 42)
44 PATH_EXPR@[39; 40)
45 PATH@[39; 40)
46 PATH_SEGMENT@[39; 40)
47 NAME_REF@[39; 40)
48 IDENT@[39; 40) "x"
49 DOT@[40; 41) "."
50 INT_NUMBER@[41; 42) "0"
51 ARG_LIST@[42; 44)
52 L_PAREN@[42; 43) "("
53 R_PAREN@[43; 44) ")"
54 SEMI@[44; 45) ";"
55 WHITESPACE@[45; 46) "\n"
56 R_CURLY@[46; 47) "}"
57 WHITESPACE@[47; 48) "\n"