parser: support declare statement with postfix block

This commit is contained in:
Ryan Chandler 2022-09-13 00:59:12 +01:00
parent bbfce83894
commit d9d3ffbb47
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
2 changed files with 56 additions and 24 deletions

View File

@ -302,6 +302,7 @@ pub enum Statement {
}, },
Declare { Declare {
declares: Vec<DeclareItem>, declares: Vec<DeclareItem>,
body: Block,
}, },
Noop, Noop,
} }

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
ast::{ ast::{
Arg, ArrayItem, BackedEnumType, ClassFlag, ClosureUse, ElseIf, IncludeKind, MagicConst, Arg, ArrayItem, BackedEnumType, ClassFlag, ClosureUse, DeclareItem, ElseIf, IncludeKind,
MethodFlag, StaticVar, Use, UseKind, DeclareItem, MagicConst, MethodFlag, StaticVar, Use, UseKind,
}, },
Block, Case, Catch, Expression, Identifier, MatchArm, Program, Statement, Type, Block, Case, Catch, Expression, Identifier, MatchArm, Program, Statement, Type,
}; };
@ -190,10 +190,19 @@ impl Parser {
} }
self.rparen()?; self.rparen()?;
self.semi()?;
Statement::Declare { declares } let body = if self.current.kind == TokenKind::LeftBrace {
}, self.next();
let b = self.block(&TokenKind::RightBrace)?;
self.rbrace()?;
b
} else {
self.semi()?;
vec![]
};
Statement::Declare { declares, body }
}
TokenKind::Global => { TokenKind::Global => {
self.next(); self.next();
@ -2176,7 +2185,9 @@ impl Display for ParseError {
mod tests { mod tests {
use super::Parser; use super::Parser;
use crate::{ use crate::{
ast::{Arg, ArrayItem, ElseIf, IncludeKind, InfixOp, MethodFlag, PropertyFlag, DeclareItem}, ast::{
Arg, ArrayItem, DeclareItem, ElseIf, IncludeKind, InfixOp, MethodFlag, PropertyFlag,
},
Catch, Expression, Identifier, Param, Statement, Type, Catch, Expression, Identifier, Param, Statement, Type,
}; };
use trunk_lexer::Lexer; use trunk_lexer::Lexer;
@ -3365,34 +3376,54 @@ mod tests {
#[test] #[test]
fn basic_declare() { fn basic_declare() {
assert_ast("<?php declare(A='B');", &[ assert_ast(
Statement::Declare { "<?php declare(A='B');",
declares: vec![ &[Statement::Declare {
DeclareItem { declares: vec![DeclareItem {
key: "A".into(), key: "A".into(),
value: Expression::ConstantString { value: "B".into() } value: Expression::ConstantString { value: "B".into() },
} }],
] body: vec![],
} }],
]); );
} }
#[test] #[test]
fn multiple_declares_in_single_statement() { fn multiple_declares_in_single_statement() {
assert_ast("<?php declare(A='B', C='D');", &[ assert_ast(
Statement::Declare { "<?php declare(A='B', C='D');",
&[Statement::Declare {
declares: vec![ declares: vec![
DeclareItem { DeclareItem {
key: "A".into(), key: "A".into(),
value: Expression::ConstantString { value: "B".into() } value: Expression::ConstantString { value: "B".into() },
}, },
DeclareItem { DeclareItem {
key: "C".into(), key: "C".into(),
value: Expression::ConstantString { value: "D".into() } value: Expression::ConstantString { value: "D".into() },
} },
] ],
} body: vec![],
]); }],
);
}
#[test]
fn declare_block() {
assert_ast(
"<?php declare(A='B') { echo 'Hello, world!'; }",
&[Statement::Declare {
declares: vec![DeclareItem {
key: "A".into(),
value: Expression::ConstantString { value: "B".into() },
}],
body: vec![Statement::Echo {
values: vec![Expression::ConstantString {
value: "Hello, world!".into(),
}],
}],
}],
);
} }
fn assert_ast(source: &str, expected: &[Statement]) { fn assert_ast(source: &str, expected: &[Statement]) {