From c9fb6990bef94b9181a0cadb141924cd8349811c Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sat, 15 Feb 2020 18:45:26 -0500 Subject: [PATCH] Support parsing `new (call_function())()` And add tests for arbitrary parenthesized expressions in `new` and `instanceof` --- src/Parser.php | 22 +++- tests/cases/parser/instanceofExpression.php | 3 + .../parser/instanceofExpression.php.diag | 1 + .../parser/instanceofExpression.php.tree | 100 ++++++++++++++ .../parser/objectCreationExpression19.php | 2 + .../objectCreationExpression19.php.diag | 1 + .../objectCreationExpression19.php.tree | 103 +++++++++++++++ .../parser/objectCreationExpression20.php | 2 + .../objectCreationExpression20.php.diag | 1 + .../objectCreationExpression20.php.tree | 124 ++++++++++++++++++ 10 files changed, 357 insertions(+), 2 deletions(-) create mode 100644 tests/cases/parser/instanceofExpression.php create mode 100644 tests/cases/parser/instanceofExpression.php.diag create mode 100644 tests/cases/parser/instanceofExpression.php.tree create mode 100644 tests/cases/parser/objectCreationExpression19.php create mode 100644 tests/cases/parser/objectCreationExpression19.php.diag create mode 100644 tests/cases/parser/objectCreationExpression19.php.tree create mode 100644 tests/cases/parser/objectCreationExpression20.php create mode 100644 tests/cases/parser/objectCreationExpression20.php.diag create mode 100644 tests/cases/parser/objectCreationExpression20.php.tree diff --git a/src/Parser.php b/src/Parser.php index 5d29b7cb..722c447e 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -2678,7 +2678,7 @@ private function parsePostfixExpressionRest($expression, $allowUpdateExpression return $this->parsePostfixExpressionRest($expression); } - if ($tokenKind === TokenKind::OpenParenToken && !$this->isParsingObjectCreationExpression) { + if ($tokenKind === TokenKind::OpenParenToken && !$this->isParsingUnparenthesizedObjectCreationExpression($expression)) { $expression = $this->parseCallExpressionRest($expression); if (!$this->checkToken(TokenKind::OpenParenToken)) { @@ -2822,6 +2822,23 @@ private function parseScopedPropertyAccessExpression($expression, $fallbackParen return $scopedPropertyAccessExpression; } + public function isParsingUnparenthesizedObjectCreationExpression($expression) { + if (!$this->isParsingObjectCreationExpression) { + return false; + } + if ($expression instanceof Token) { + return true; + } + while ($expression->parent) { + $expression = $expression->parent; + if ($expression instanceof ObjectCreationExpression) { + return true; + } elseif ($expression instanceof ParenthesizedExpression) { + return false; + } + } + } + private $isParsingObjectCreationExpression = false; private function parseObjectCreationExpression($parentNode) { @@ -2829,12 +2846,13 @@ private function parseObjectCreationExpression($parentNode) { $objectCreationExpression->parent = $parentNode; $objectCreationExpression->newKeword = $this->eat1(TokenKind::NewKeyword); // TODO - add tests for this scenario + $oldIsParsingObjectCreationExpression = $this->isParsingObjectCreationExpression; $this->isParsingObjectCreationExpression = true; $objectCreationExpression->classTypeDesignator = $this->eatOptional1(TokenKind::ClassKeyword) ?? $this->parseExpression($objectCreationExpression); - $this->isParsingObjectCreationExpression = false; + $this->isParsingObjectCreationExpression = $oldIsParsingObjectCreationExpression; $objectCreationExpression->openParen = $this->eatOptional1(TokenKind::OpenParenToken); if ($objectCreationExpression->openParen !== null) { diff --git a/tests/cases/parser/instanceofExpression.php b/tests/cases/parser/instanceofExpression.php new file mode 100644 index 00000000..c8e370b9 --- /dev/null +++ b/tests/cases/parser/instanceofExpression.php @@ -0,0 +1,3 @@ +