Parse and validate attributes in blocks

This commit is contained in:
DJMcNab
2019-01-28 20:03:56 +00:00
parent 137b1ccb71
commit 00e6b5d26c
10 changed files with 352 additions and 0 deletions

View File

@@ -272,6 +272,7 @@ impl ToOwned for Block {
}
impl ast::AttrsOwner for Block {}
impl Block {
pub fn statements(&self) -> impl Iterator<Item = &Stmt> {
super::children(self)

View File

@@ -571,6 +571,9 @@ Grammar(
options: [ "Expr" ],
collections: [
["statements", "Stmt"],
],
traits: [
"AttrsOwner",
]
),
"ParamList": (

View File

@@ -42,6 +42,8 @@ pub(crate) fn block(p: &mut Parser) {
}
let m = p.start();
p.bump();
// This is checked by a validator
attributes::inner_attributes(p);
while !p.at(EOF) && !p.at(R_CURLY) {
match p.current() {

View File

@@ -2,6 +2,7 @@ mod byte;
mod byte_string;
mod char;
mod string;
mod block;
use crate::{
SourceFile, yellow::SyntaxError, AstNode,
@@ -17,6 +18,7 @@ pub(crate) fn validate(file: &SourceFile) -> Vec<SyntaxError> {
.visit::<ast::ByteString, _>(self::byte_string::validate_byte_string_node)
.visit::<ast::Char, _>(self::char::validate_char_node)
.visit::<ast::String, _>(self::string::validate_string_node)
.visit::<ast::Block, _>(self::block::validate_block_node)
.accept(node);
}
errors

View File

@@ -0,0 +1,24 @@
use crate::{SyntaxKind::*,
ast::{self, AttrsOwner, AstNode},
yellow::{
SyntaxError,
SyntaxErrorKind::*,
},
};
pub(crate) fn validate_block_node(node: &ast::Block, errors: &mut Vec<SyntaxError>) {
if let Some(parent) = node.syntax().parent() {
match parent.kind() {
FN_DEF => return,
BLOCK_EXPR => match parent.parent().map(|v| v.kind()) {
Some(EXPR_STMT) | Some(BLOCK) => return,
_ => {}
},
_ => {}
}
}
errors.extend(
node.attrs()
.map(|attr| SyntaxError::new(InvalidBlockAttr, attr.syntax().range())),
)
}

View File

@@ -94,6 +94,7 @@ pub enum SyntaxErrorKind {
UnicodeEscapeOutOfRange,
UnclosedString,
InvalidSuffix,
InvalidBlockAttr,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -136,6 +137,9 @@ impl fmt::Display for SyntaxErrorKind {
UnicodeEscapeOutOfRange => write!(f, "Unicode escape code should be at most 0x10FFFF"),
UnclosedString => write!(f, "Unclosed string literal"),
InvalidSuffix => write!(f, "Invalid literal suffix"),
InvalidBlockAttr => {
write!(f, "A block in this position cannot accept inner attributes")
}
ParseError(msg) => write!(f, "{}", msg.0),
}
}