Skip to content

Commit

Permalink
PHP 8.0 | ControlStructures::hasBody(): add support for match express…
Browse files Browse the repository at this point in the history
…ions

PHP 8.0 introduced match expressions as an new control structure.

While a `match` expression without body or with an empty body is not allowed and would result in a fatal error (or be interpreted as a non-global function call), the `ControlStructures::hasBody()` method should still handle it correctly.

Includes adding the `T_MATCH` token to the `Collections::controlStructureTokens()` token array.

Includes unit tests.

Refs:
* https://wiki.php.net/rfc/match_expression_v2
  • Loading branch information
jrfnl committed Oct 15, 2022
1 parent f5f91ee commit c5a9956
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 0 deletions.
2 changes: 2 additions & 0 deletions PHPCSUtils/Tokens/Collections.php
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ class Collections
* DEPRECATED: Control structure tokens.
*
* @since 1.0.0-alpha2
* @since 1.0.0-alpha4 Added the T_MATCH token for PHP 8.0 match expressions.
*
* @deprecated 1.0.0-alpha4 Use the {@see Collections::controlStructureTokens()} method instead.
*
Expand All @@ -217,6 +218,7 @@ class Collections
\T_DO => \T_DO,
\T_WHILE => \T_WHILE,
\T_DECLARE => \T_DECLARE,
\T_MATCH => \T_MATCH,
];

/**
Expand Down
1 change: 1 addition & 0 deletions PHPCSUtils/Utils/ControlStructures.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ControlStructures
* regarded as empty.
*
* @since 1.0.0
* @since 1.0.0-alpha4 Added support for PHP 8.0 match control structures.
*
* @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned.
* @param int $stackPtr The position of the token we are checking.
Expand Down
22 changes: 22 additions & 0 deletions Tests/Utils/ControlStructures/HasBodyTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,28 @@ do
echo $i;
while (++$i <= 10);


/*
* PHP 8.0 match expressions.
*/

/* testMatchEmptyBody */
// Intentional fatal error, "unhandled match case", but not the concern of this method.
$match = match($a) {};

/* testMatchEmptyBodyWithComment */
// Intentional fatal error, "unhandled match case", but not the concern of this method.
$match = match($a) {
// Deliberately empty.
};

/* testMatchWithCode */
$match = match ($a) {
0 => 'Foo',
1 => 'Bar',
2 => 'Baz',
};

// Live coding.
// Intentional parse error. This test has to be the last in the file.
if ($a) {
Expand Down
23 changes: 23 additions & 0 deletions Tests/Utils/ControlStructures/HasBodyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,29 @@ public function dataHasBody()
'hasBody' => true,
'hasNonEmptyBody' => true,
],

/*
* Match without body cannot be tested as, in that case, `match` will tokenize as `T_STRING`.
* Without body (`match();`), match will either yield a parse error
* or be interpreted as a function call (`\match();` or `self::match()` etc).
*/

'match-empty-body' => [
'testMarker' => '/* testMatchEmptyBody */',
'hasBody' => true,
'hasNonEmptyBody' => false,
],
'match-empty-body-comment-only' => [
'testMarker' => '/* testMatchEmptyBodyWithComment */',
'hasBody' => true,
'hasNonEmptyBody' => false,
],
'match-with-code' => [
'testMarker' => '/* testMatchWithCode */',
'hasBody' => true,
'hasNonEmptyBody' => true,
],

'else-live-coding' => [
'testMarker' => '/* testElseLiveCoding */',
'hasBody' => true,
Expand Down

0 comments on commit c5a9956

Please sign in to comment.