Merge pull request #53 from ryangjchandler/fix/catch-without-variable

This commit is contained in:
Ryan Chandler 2022-09-13 00:33:27 +01:00 committed by GitHub
commit 9358503d3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 3 deletions

View File

@ -343,7 +343,7 @@ pub struct Case {
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct Catch {
pub types: Vec<Identifier>,
pub var: Expression,
pub var: Option<Expression>,
pub body: Block,
}

View File

@ -883,7 +883,11 @@ impl Parser {
_ => return Err(ParseError::InvalidCatchArgumentType(self.current.span)),
};
let var = self.expression(0)?;
let var = if self.current.kind == TokenKind::RightParen {
None
} else {
Some(self.expression(0)?)
};
self.rparen()?;
self.lbrace()?;
@ -2117,7 +2121,7 @@ mod tests {
use super::Parser;
use crate::{
ast::{Arg, ArrayItem, ElseIf, IncludeKind, InfixOp, MethodFlag, PropertyFlag},
Expression, Identifier, Param, Statement, Type,
Catch, Expression, Identifier, Param, Statement, Type,
};
use trunk_lexer::Lexer;
@ -3188,6 +3192,89 @@ mod tests {
);
}
#[test]
fn try_catch() {
assert_ast(
"<?php try {} catch (Exception $e) {}",
&[Statement::Try {
body: vec![],
catches: vec![Catch {
types: vec!["Exception".into()],
var: Some(Expression::Variable { name: "e".into() }),
body: vec![],
}],
finally: None,
}],
);
}
#[test]
fn try_catch_no_variable() {
assert_ast(
"<?php try {} catch (Exception) {}",
&[Statement::Try {
body: vec![],
catches: vec![Catch {
types: vec!["Exception".into()],
var: None,
body: vec![],
}],
finally: None,
}],
);
}
#[test]
fn try_catch_multiple_catches() {
assert_ast(
"<?php try {} catch (Exception $e) {} catch (CustomException $e) {}",
&[Statement::Try {
body: vec![],
catches: vec![
Catch {
types: vec!["Exception".into()],
var: Some(Expression::Variable { name: "e".into() }),
body: vec![],
},
Catch {
types: vec!["CustomException".into()],
var: Some(Expression::Variable { name: "e".into() }),
body: vec![],
},
],
finally: None,
}],
);
}
#[test]
fn try_catch_finally() {
assert_ast(
"<?php try {} catch (Exception $e) {} finally {}",
&[Statement::Try {
body: vec![],
catches: vec![Catch {
types: vec!["Exception".into()],
var: Some(Expression::Variable { name: "e".into() }),
body: vec![],
}],
finally: Some(vec![]),
}],
);
}
#[test]
fn try_finally_no_catch() {
assert_ast(
"<?php try {} finally {}",
&[Statement::Try {
body: vec![],
catches: vec![],
finally: Some(vec![]),
}],
);
}
fn assert_ast(source: &str, expected: &[Statement]) {
let mut lexer = Lexer::new(None);
let tokens = lexer.tokenize(source).unwrap();