Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PHP 8.0] Add match expressions #672

Merged
merged 26 commits into from Jul 15, 2020
Merged

[PHP 8.0] Add match expressions #672

merged 26 commits into from Jul 15, 2020

Conversation

TomasVotruba
Copy link
Contributor

@TomasVotruba TomasVotruba commented Jun 22, 2020

// After
$statement = match ($this->lexer->lookahead['type']) {
    Lexer::T_SELECT => $this->SelectStatement(),
    Lexer::T_UPDATE => $this->UpdateStatement(),
    Lexer::T_DELETE => $this->DeleteStatement(),
    default => $this->syntaxError('SELECT, UPDATE or DELETE'),
};

@TomasVotruba
Copy link
Contributor Author

Ready for review

@TomasVotruba
Copy link
Contributor Author

TomasVotruba commented Jun 22, 2020

The failing job is related to offical PHP tests fixture, that is using "match" in function name function match(): https://github.com/php/php-src/blob/dad377ba5774bf624a0f111d0eca274053124b87/ext/standard/tests/file/fnmatch_variation.phpt#L81

It was fixed in the RFC PR:

image

So not related to this PR.

@@ -1256,6 +1256,7 @@ protected function initializeInsertionMap() {
'Expr_Yield->value' => [\T_YIELD, false, ' ', null],
'Param->type' => [null, false, null, ' '],
'Param->default' => [null, false, ' = ', null],
'Stmt_MatchArm->body' => [null, false, ', ', null],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this is the way to add a comma after specific subnode, but it doesn't work.
Any tips?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list only takes effect if body is changed from null to Expr, which can't happen. You need the ListInsertionMap for new match arms / new match conditions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

grammar/php7.y Outdated Show resolved Hide resolved
grammar/php7.y Outdated Show resolved Hide resolved
grammar/php7.y Outdated Show resolved Hide resolved
grammar/php7.y Outdated Show resolved Hide resolved
public function emulate(string $code, array $tokens): array
{
// We need to manually iterate and manage a count because we'll change
// the tokens array on the way
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't make sense here (we don't maintain a manual count).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only copy pasted from other emulator classes. Should it be removed everywhere or just here?

lib/PhpParser/Node/Expr/Match_.php Outdated Show resolved Hide resolved
lib/PhpParser/Node/Stmt/MatchArm.php Outdated Show resolved Hide resolved
lib/PhpParser/Node/Stmt/MatchArm.php Outdated Show resolved Hide resolved
@@ -12,8 +12,6 @@ class Switch_ extends Node\Stmt
public $cases;

/**
* Constructs a case node.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep this, it's present everywhere. Makes little sense to drop it in only one case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes little sense to drop it in only one case.

My bad. Intent was to clear comment without any value. Will handle the rest of comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes little sense to drop it in only one case.

My bad. Intent was to clear comment without any value. Will handle the rest of comments.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes little sense to drop it in only one case.

My bad. Intent was to clear comment without any value. Will handle the rest of comments.

@@ -1256,6 +1256,7 @@ protected function initializeInsertionMap() {
'Expr_Yield->value' => [\T_YIELD, false, ' ', null],
'Param->type' => [null, false, null, ' '],
'Param->default' => [null, false, ' = ', null],
'Stmt_MatchArm->body' => [null, false, ', ', null],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list only takes effect if body is changed from null to Expr, which can't happen. You need the ListInsertionMap for new match arms / new match conditions.

@@ -1326,6 +1326,8 @@ protected function initializeListInsertionMap() {
'Stmt_TraitUseAdaptation_Precedence->insteadof' => ', ',
'Stmt_Unset->vars' => ', ',
'Stmt_Use->uses' => ', ',
'Stmt_Arm->condList' => ', ',
'Stmt_Match->arms' => ', ',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct? The comma is still missing in the print :P

@@ -1326,6 +1326,8 @@ protected function initializeListInsertionMap() {
'Stmt_TraitUseAdaptation_Precedence->insteadof' => ', ',
'Stmt_Unset->vars' => ', ',
'Stmt_Use->uses' => ', ',
'Stmt_Arm->condList' => ', ',
'Stmt_Match->arms' => ', ',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct? The comma is still missing in the print :/

@TomasVotruba
Copy link
Contributor Author

Updated

This reverts commit b822acc.

Reduce unnecessary diff.
These have been added upstream as well.
This is not a statement, and just "Arm" is a bit too generic.
This seems more in line with other names like "stmts".
This has more failures, but it's more honest about which PHP 8
features we don't support yet ...
@nikic nikic merged commit 69c5d48 into nikic:master Jul 15, 2020
@TomasVotruba TomasVotruba deleted the php80-match-expression-v2 branch July 15, 2020 21:07
@TomasVotruba
Copy link
Contributor Author

TomasVotruba commented Jul 15, 2020

Thanks for finishing it!

Do you recall where I messed up the grammar so the commas after arms were missing?

@nikic
Copy link
Owner

nikic commented Jul 15, 2020

@TomasVotruba I think everything in the grammar was right, the problem was was the use of pStmts() instead of pCommaSeparatedMultiline() inside the pretty-printer.

@TomasVotruba
Copy link
Contributor Author

I thought I tried both with same bad result. Well, maybe I overlooked it.

Thanks for letting me know 👍 , I'll be patient to it next time

@ondrejmirtes
Copy link
Contributor

Is it expected that Emulative lexer will break on existing PHP 7-level code? I'd say that people use Emulative when they want to parse features from newer PHP versions on an older PHP version.

But this change means that the Emulative lexer will fail with parse error on interface Match which is valid on PHP 7. Which is pretty inconvenient as PHPUnit contains this interface.

@nikic
Copy link
Owner

nikic commented Jul 16, 2020

@ondrejmirtes Unfortunately the emulative lexer currently only does emulation in one direction. Emulation in the other direction (and ability to pick a precise PHP version to target) would have to be implemented.

leofeyer added a commit to contao/contao that referenced this pull request Jul 27, 2020
Description
-----------

As of version 4.7, the PHP parser supports PHP 8 match expressions, which unfortunately [breaks PHPUnit](nikic/PHP-Parser#672 (comment)) under PHP 7.4.

```
ERROR: ParseError - vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php:15:35 - Syntax error, unexpected T_MATCH on line 15 (see https://psalm.dev/173)
interface ParametersMatch extends Match


ERROR: ParseError - vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php:34:40 - Syntax error, unexpected ';', expecting '{' on line 34 (see https://psalm.dev/173)
    public function with(...$arguments);


ERROR: ParseError - vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php:47:40 - Syntax error, unexpected ';', expecting '{' on line 47 (see https://psalm.dev/173)
    public function withAnyParameters();
```

The issue has been reported in nikic/PHP-Parser#690, so I hope it will be fixed in version 4.7.1.

Commits
-------

00ed9a0 Add a conflict with nikic/php-parser
AlexejKossmann pushed a commit to AlexejKossmann/contao that referenced this pull request Apr 6, 2021
Description
-----------

As of version 4.7, the PHP parser supports PHP 8 match expressions, which unfortunately [breaks PHPUnit](nikic/PHP-Parser#672 (comment)) under PHP 7.4.

```
ERROR: ParseError - vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php:15:35 - Syntax error, unexpected T_MATCH on line 15 (see https://psalm.dev/173)
interface ParametersMatch extends Match

ERROR: ParseError - vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php:34:40 - Syntax error, unexpected ';', expecting '{' on line 34 (see https://psalm.dev/173)
    public function with(...$arguments);

ERROR: ParseError - vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php:47:40 - Syntax error, unexpected ';', expecting '{' on line 47 (see https://psalm.dev/173)
    public function withAnyParameters();
```

The issue has been reported in nikic/PHP-Parser#690, so I hope it will be fixed in version 4.7.1.

Commits
-------

00ed9a0 Add a conflict with nikic/php-parser
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[PHP 8.0] Add match expression v2
3 participants