aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
authorDJMcNab <[email protected]>2019-01-28 20:03:56 +0000
committerDJMcNab <[email protected]>2019-01-28 20:03:56 +0000
commit00e6b5d26c82d5faff066c24418a0eb5741efcd1 (patch)
tree82ad741bab4f820850ba6f13e2b760cc840f43fb /crates/ra_syntax/src
parent137b1ccb715fe795cdf6c528bef6f8df3387f158 (diff)
Parse and validate attributes in blocks
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/ast/generated.rs1
-rw-r--r--crates/ra_syntax/src/grammar.ron3
-rw-r--r--crates/ra_syntax/src/grammar/expressions.rs2
-rw-r--r--crates/ra_syntax/src/validation.rs2
-rw-r--r--crates/ra_syntax/src/validation/block.rs24
-rw-r--r--crates/ra_syntax/src/yellow/syntax_error.rs4
6 files changed, 36 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 3ace6533c..ce559882b 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -272,6 +272,7 @@ impl ToOwned for Block {
272} 272}
273 273
274 274
275impl ast::AttrsOwner for Block {}
275impl Block { 276impl Block {
276 pub fn statements(&self) -> impl Iterator<Item = &Stmt> { 277 pub fn statements(&self) -> impl Iterator<Item = &Stmt> {
277 super::children(self) 278 super::children(self)
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index 85fc79038..f4841241f 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -571,6 +571,9 @@ Grammar(
571 options: [ "Expr" ], 571 options: [ "Expr" ],
572 collections: [ 572 collections: [
573 ["statements", "Stmt"], 573 ["statements", "Stmt"],
574 ],
575 traits: [
576 "AttrsOwner",
574 ] 577 ]
575 ), 578 ),
576 "ParamList": ( 579 "ParamList": (
diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs
index d27eb8b7e..6b88c5685 100644
--- a/crates/ra_syntax/src/grammar/expressions.rs
+++ b/crates/ra_syntax/src/grammar/expressions.rs
@@ -42,6 +42,8 @@ pub(crate) fn block(p: &mut Parser) {
42 } 42 }
43 let m = p.start(); 43 let m = p.start();
44 p.bump(); 44 p.bump();
45 // This is checked by a validator
46 attributes::inner_attributes(p);
45 47
46 while !p.at(EOF) && !p.at(R_CURLY) { 48 while !p.at(EOF) && !p.at(R_CURLY) {
47 match p.current() { 49 match p.current() {
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs
index 73e1d20b9..ac6cc3dd6 100644
--- a/crates/ra_syntax/src/validation.rs
+++ b/crates/ra_syntax/src/validation.rs
@@ -2,6 +2,7 @@ mod byte;
2mod byte_string; 2mod byte_string;
3mod char; 3mod char;
4mod string; 4mod string;
5mod block;
5 6
6use crate::{ 7use crate::{
7 SourceFile, yellow::SyntaxError, AstNode, 8 SourceFile, yellow::SyntaxError, AstNode,
@@ -17,6 +18,7 @@ pub(crate) fn validate(file: &SourceFile) -> Vec<SyntaxError> {
17 .visit::<ast::ByteString, _>(self::byte_string::validate_byte_string_node) 18 .visit::<ast::ByteString, _>(self::byte_string::validate_byte_string_node)
18 .visit::<ast::Char, _>(self::char::validate_char_node) 19 .visit::<ast::Char, _>(self::char::validate_char_node)
19 .visit::<ast::String, _>(self::string::validate_string_node) 20 .visit::<ast::String, _>(self::string::validate_string_node)
21 .visit::<ast::Block, _>(self::block::validate_block_node)
20 .accept(node); 22 .accept(node);
21 } 23 }
22 errors 24 errors
diff --git a/crates/ra_syntax/src/validation/block.rs b/crates/ra_syntax/src/validation/block.rs
new file mode 100644
index 000000000..9e1949124
--- /dev/null
+++ b/crates/ra_syntax/src/validation/block.rs
@@ -0,0 +1,24 @@
1use crate::{SyntaxKind::*,
2 ast::{self, AttrsOwner, AstNode},
3 yellow::{
4 SyntaxError,
5 SyntaxErrorKind::*,
6 },
7};
8
9pub(crate) fn validate_block_node(node: &ast::Block, errors: &mut Vec<SyntaxError>) {
10 if let Some(parent) = node.syntax().parent() {
11 match parent.kind() {
12 FN_DEF => return,
13 BLOCK_EXPR => match parent.parent().map(|v| v.kind()) {
14 Some(EXPR_STMT) | Some(BLOCK) => return,
15 _ => {}
16 },
17 _ => {}
18 }
19 }
20 errors.extend(
21 node.attrs()
22 .map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().range())),
23 )
24}
diff --git a/crates/ra_syntax/src/yellow/syntax_error.rs b/crates/ra_syntax/src/yellow/syntax_error.rs
index 534f3511e..c52c44cc3 100644
--- a/crates/ra_syntax/src/yellow/syntax_error.rs
+++ b/crates/ra_syntax/src/yellow/syntax_error.rs
@@ -94,6 +94,7 @@ pub enum SyntaxErrorKind {
94 UnicodeEscapeOutOfRange, 94 UnicodeEscapeOutOfRange,
95 UnclosedString, 95 UnclosedString,
96 InvalidSuffix, 96 InvalidSuffix,
97 InvalidBlockAttr,
97} 98}
98 99
99#[derive(Debug, Clone, PartialEq, Eq, Hash)] 100#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -136,6 +137,9 @@ impl fmt::Display for SyntaxErrorKind {
136 UnicodeEscapeOutOfRange => write!(f, "Unicode escape code should be at most 0x10FFFF"), 137 UnicodeEscapeOutOfRange => write!(f, "Unicode escape code should be at most 0x10FFFF"),
137 UnclosedString => write!(f, "Unclosed string literal"), 138 UnclosedString => write!(f, "Unclosed string literal"),
138 InvalidSuffix => write!(f, "Invalid literal suffix"), 139 InvalidSuffix => write!(f, "Invalid literal suffix"),
140 InvalidBlockAttr => {
141 write!(f, "A block in this position cannot accept inner attributes")
142 }
139 ParseError(msg) => write!(f, "{}", msg.0), 143 ParseError(msg) => write!(f, "{}", msg.0),
140 } 144 }
141 } 145 }