parser: support method calls

This commit is contained in:
Ryan Chandler 2022-07-26 11:29:42 +01:00
parent 2d332f90e4
commit ce57758042
No known key found for this signature in database
GPG Key ID: F113BCADDB3B0CCA
3 changed files with 58 additions and 2 deletions

View File

@ -1,3 +1,9 @@
<?php
$foo->bar();
$foo->bar();
$foo->bar(1, 2, 3);
$foo->bar()->baz();
$foo->bar->baz();
$foo->bar()();

View File

@ -239,6 +239,7 @@ pub enum Expression {
New(Box<Self>, Vec<Self>),
ConstantString(String),
PropertyFetch(Box<Self>, Identifier),
MethodCall(Box<Self>, Identifier, Vec<Self>),
}
#[derive(Debug, Clone, PartialEq, Serialize)]

View File

@ -884,7 +884,22 @@ impl Parser {
let property = expect!(self, TokenKind::Identifier(i), i, "expected identifier");
if self.current.kind == TokenKind::LeftParen {
todo!("parse method calls");
self.next();
let mut args = Vec::new();
while self.current.kind != TokenKind::RightParen {
let arg = self.expression(0)?;
if self.current.kind == TokenKind::Comma {
self.next();
}
args.push(arg);
}
expect!(self, TokenKind::RightParen, "expected )");
Expression::MethodCall(Box::new(lhs), property.into(), args)
} else {
Expression::PropertyFetch(Box::new(lhs), property.into())
}
@ -1090,6 +1105,40 @@ mod tests {
]);
}
#[test]
fn method_calls() {
assert_ast("<?php $foo->bar();", &[
expr!(Expression::MethodCall(
Box::new(Expression::Variable("foo".into())),
Identifier::from("bar"),
vec![]
))
]);
assert_ast("<?php $foo->bar()->baz();", &[
expr!(Expression::MethodCall(
Box::new(Expression::MethodCall(
Box::new(Expression::Variable("foo".into())),
Identifier::from("bar"),
vec![]
)),
Identifier::from("baz"),
vec![]
))
]);
assert_ast("<?php $foo->bar()();", &[
expr!(Expression::Call(
Box::new(Expression::MethodCall(
Box::new(Expression::Variable("foo".into())),
Identifier::from("bar"),
vec![]
)),
vec![]
))
]);
}
#[test]
fn concat() {
assert_ast("<?php 'foo' . 'bar' . 'baz';", &[