Skip to content

Commit 16645d7

Browse files
authored
Merge pull request #618 from PHPCSStandards/php-8.4/update-for-exit-as-function-call
PHP 8.4: updates for exit as function call
2 parents 482407c + 15deff1 commit 16645d7

File tree

11 files changed

+99
-7
lines changed

11 files changed

+99
-7
lines changed

PHPCSUtils/Tokens/Collections.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,10 @@ public static function functionCallTokens()
692692
$tokens[\T_ANON_CLASS] = \T_ANON_CLASS;
693693
$tokens += self::$ooHierarchyKeywords;
694694

695+
// As of PHP 8.4, exit()/die() should be treated as function call tokens.
696+
// Sniffs using this collection should safeguard against use as a constant.
697+
$tokens[\T_EXIT] = \T_EXIT;
698+
695699
return $tokens;
696700
}
697701

PHPCSUtils/Utils/PassedParameters.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ final class PassedParameters
6565
* a short array opener.
6666
* - If passed a `T_ISSET` or `T_UNSET` stack pointer, it will detect whether those
6767
* language constructs have "parameters".
68+
* - If passed a `T_EXIT` stack pointer, it will treat it as a function call and detect whether
69+
* it has been passed parameters. When the `T_EXIT` is used as a constant, the return value
70+
* will be `false` (no parameters).
6871
*
6972
* @since 1.0.0
7073
*
@@ -94,7 +97,7 @@ public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray =
9497
throw OutOfBoundsStackPtr::create(2, '$stackPtr', $stackPtr);
9598
}
9699

97-
$acceptedTokens = 'function call, array, isset or unset';
100+
$acceptedTokens = 'function call, array, isset, unset or exit';
98101
if (isset(Collections::parameterPassingTokens()[$tokens[$stackPtr]['code']]) === false) {
99102
throw UnexpectedTokenType::create(2, '$stackPtr', $acceptedTokens, $tokens[$stackPtr]['type']);
100103
}
@@ -131,7 +134,7 @@ public static function hasParameters(File $phpcsFile, $stackPtr, $isShortArray =
131134
return true;
132135
}
133136

134-
// Deal with function calls, long arrays, isset and unset.
137+
// Deal with function calls, long arrays, isset, unset and exit/die.
135138
// Next non-empty token should be the open parenthesis.
136139
if ($tokens[$next]['code'] !== \T_OPEN_PARENTHESIS) {
137140
return false;

Tests/Tokens/Collections/FunctionCallTokensTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function testFunctionCallTokens()
4040
\T_PARENT => \T_PARENT,
4141
\T_SELF => \T_SELF,
4242
\T_STATIC => \T_STATIC,
43+
\T_EXIT => \T_EXIT,
4344
];
4445

4546
$this->assertSame($expected, Collections::functionCallTokens());

Tests/Tokens/Collections/ParameterPassingTokensTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public function testParameterPassingTokens()
4040
\T_PARENT => \T_PARENT,
4141
\T_SELF => \T_SELF,
4242
\T_STATIC => \T_STATIC,
43+
\T_EXIT => \T_EXIT,
4344
\T_ISSET => \T_ISSET,
4445
\T_UNSET => \T_UNSET,
4546
\T_ARRAY => \T_ARRAY,

Tests/Utils/PassedParameters/GetParametersNamedTest.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ foo( label: $cond ? true : false, more: $cond ? CONSTANT_A : CONSTANT_B );
5353
/* testTernaryWithFunctionCallsInThenElse */
5454
echo $cond ? foo( label: $something ) : /* testTernaryWithFunctionCallsInElse */ bar( more: $something_else );
5555

56+
/* testExitWithNamedParam */
57+
exit( status: 1 );
58+
5659
/* testCompileErrorNamedBeforePositional */
5760
// Not the concern of PHPCSUtils. Should still be handled.
5861
test(param: $bar, $foo);

Tests/Utils/PassedParameters/GetParametersNamedTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,20 @@ public static function dataGetParameters()
426426
],
427427
],
428428
],
429+
'named-args-for-exit' => [
430+
'testMarker' => '/* testExitWithNamedParam */',
431+
'targetType' => \T_EXIT,
432+
'expected' => [
433+
'status' => [
434+
'name' => 'status',
435+
'name_token' => 3,
436+
'start' => 5,
437+
'end' => 7,
438+
'raw' => '1',
439+
],
440+
],
441+
],
442+
429443
'named-args-compile-error-named-before-positional' => [
430444
'testMarker' => '/* testCompileErrorNamedBeforePositional */',
431445
'targetType' => \T_STRING,

Tests/Utils/PassedParameters/GetParametersSkipShortArrayCheckTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function testHasParametersDontSkipShortArrayCheck($testMarker, $targetTyp
4545
if ($expectException === true) {
4646
$this->expectException('PHPCSUtils\Exceptions\UnexpectedTokenType');
4747
$this->expectExceptionMessage(
48-
'Argument #2 ($stackPtr) must be of type function call, array, isset or unset;'
48+
'Argument #2 ($stackPtr) must be of type function call, array, isset, unset or exit;'
4949
);
5050
}
5151

@@ -96,7 +96,7 @@ public function testGetParametersSkipShortArrayCheck($testMarker, $targetType, $
9696
if ($targetType === \T_OPEN_SQUARE_BRACKET) {
9797
$this->expectException('PHPCSUtils\Exceptions\UnexpectedTokenType');
9898
$this->expectExceptionMessage(
99-
'Argument #2 ($stackPtr) must be of type function call, array, isset or unset;'
99+
'Argument #2 ($stackPtr) must be of type function call, array, isset, unset or exit;'
100100
);
101101
}
102102

Tests/Utils/PassedParameters/GetParametersTest.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ if ( isset(
120120
/* testUnset */
121121
unset( $variable, $object->property, static::$property, $array[$name], );
122122

123+
/* testDie */
124+
die( $status );
125+
123126
/* testAnonClass */
124127
$anon = new class( $param1, $param2 ) {
125128
public function __construct($param1, $param2) {}

Tests/Utils/PassedParameters/GetParametersTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,18 @@ public function test( $foo, $bar ) {
523523
],
524524
],
525525
],
526+
'die' => [
527+
'testMarker' => '/* testDie */',
528+
'targetType' => \T_EXIT,
529+
'expected' => [
530+
1 => [
531+
'start' => 2,
532+
'end' => 4,
533+
'raw' => '$status',
534+
],
535+
],
536+
],
537+
526538
'anon-class' => [
527539
'testMarker' => '/* testAnonClass */',
528540
'targetType' => \T_ANON_CLASS,

Tests/Utils/PassedParameters/HasParametersTest.inc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ class Foo {
1919
/* testShortListNotShortArray */
2020
[ $a, $b ] = $array;
2121

22+
/* testExitAsConstant */
23+
exit;
24+
25+
/* testDieAsConstant */
26+
die;
27+
28+
2229
// Function calls: no parameters.
2330

2431
/* testNoParamsFunctionCall1 */
@@ -163,6 +170,18 @@ unset(
163170

164171
);
165172

173+
/* testNoParamsExit */
174+
exit();
175+
176+
/* testHasParamsExit */
177+
exit( $code );
178+
179+
/* testNoParamsDie */
180+
die( /*comment*/ );
181+
182+
/* testHasParamsDie */
183+
die( $status );
184+
166185
/* testNoParamsNoParensAnonClass */
167186
$anon = new class extends FooBar {};
168187

0 commit comments

Comments
 (0)