Skip to content

Commit c7f7013

Browse files
committed
PHP 8.0 | Tokenizer/PHP: bugfix for union type operator tokenization
In `PHP::processAdditional()`, in the part which retokenizes `T_BITWISE_OR` tokens to `T_TYPE_UNION`, the code already took reference operators and spread operators between the type declaration and the variable into account, but would also increment the current position in the loop, while this is already done in the `for()`. My bad. Fixed now. Includes additional unit tests for all relevant functions within the chain, as well as for the sniff for which the issue was reported. Fixes 3267
1 parent 46715ed commit c7f7013

File tree

7 files changed

+46
-1
lines changed

7 files changed

+46
-1
lines changed

src/Standards/PSR12/Tests/Operators/OperatorSpacingUnitTest.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,5 @@ $fn = fn(array &$one) => 1;
6161
$fn = fn(array & $one) => 1;
6262

6363
$fn = static fn(DateTime $a, DateTime $b): int => -($a->getTimestamp() <=> $b->getTimestamp());
64+
65+
function issue3267(string|int ...$values) {}

src/Standards/PSR12/Tests/Operators/OperatorSpacingUnitTest.inc.fixed

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,5 @@ $fn = fn(array &$one) => 1;
6161
$fn = fn(array & $one) => 1;
6262

6363
$fn = static fn(DateTime $a, DateTime $b): int => -($a->getTimestamp() <=> $b->getTimestamp());
64+
65+
function issue3267(string|int ...$values) {}

src/Tokenizers/PHP.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2540,7 +2540,6 @@ protected function processAdditional()
25402540
|| $this->tokens[$x]['code'] === T_ELLIPSIS)
25412541
) {
25422542
// Skip past reference and variadic indicators for parameter types.
2543-
++$x;
25442543
continue;
25452544
}
25462545

tests/Core/File/GetMethodParametersTest.inc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ function namespaceOperatorTypeHint(?namespace\Name $var1) {}
4545
/* testPHP8UnionTypesSimple */
4646
function unionTypeSimple(int|float $number, self|parent &...$obj) {}
4747

48+
/* testPHP8UnionTypesWithSpreadOperatorAndReference */
49+
function globalFunctionWithSpreadAndReference(float|null &$paramA, string|int ...$paramB) {}
50+
4851
/* testPHP8UnionTypesSimpleWithBitwiseOrInDefault */
4952
$fn = fn(int|float $var = CONSTANT_A | CONSTANT_B) => $var;
5053

tests/Core/File/GetMethodParametersTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,36 @@ public function testPHP8UnionTypesSimple()
370370
}//end testPHP8UnionTypesSimple()
371371

372372

373+
/**
374+
* Verify recognition of PHP8 union type declaration when the variable has either a spread operator or a reference.
375+
*
376+
* @return void
377+
*/
378+
public function testPHP8UnionTypesWithSpreadOperatorAndReference()
379+
{
380+
$expected = [];
381+
$expected[0] = [
382+
'name' => '$paramA',
383+
'content' => 'float|null &$paramA',
384+
'pass_by_reference' => true,
385+
'variable_length' => false,
386+
'type_hint' => 'float|null',
387+
'nullable_type' => false,
388+
];
389+
$expected[1] = [
390+
'name' => '$paramB',
391+
'content' => 'string|int ...$paramB',
392+
'pass_by_reference' => false,
393+
'variable_length' => true,
394+
'type_hint' => 'string|int',
395+
'nullable_type' => false,
396+
];
397+
398+
$this->getMethodParametersTestHelper('/* '.__FUNCTION__.' */', $expected);
399+
400+
}//end testPHP8UnionTypesWithSpreadOperatorAndReference()
401+
402+
373403
/**
374404
* Verify recognition of PHP8 union type declaration with a bitwise or in the default value.
375405
*

tests/Core/Tokenizer/BitwiseOrTest.inc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ class TypeUnion
4848
/* testTypeUnionClosureParamIllegalNullable */
4949
$closureWithParamType = function (?string|null $string) {};
5050

51+
function globalFunctionWithSpreadAndReference(
52+
/* testTypeUnionWithReference */
53+
float|null &$paramA,
54+
/* testTypeUnionWithSpreadOperator */
55+
string|int ...$paramB
56+
) {}
57+
5158
/* testBitwiseOrClosureParamDefault */
5259
$closureWithReturnType = function ($string = NONSENSE | FAKE)/* testTypeUnionClosureReturn */ : \Package\MyA|PackageB {};
5360

tests/Core/Tokenizer/BitwiseOrTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ public function dataTypeUnion()
110110
['/* testTypeUnionAbstractMethodReturnType1 */'],
111111
['/* testTypeUnionAbstractMethodReturnType2 */'],
112112
['/* testTypeUnionClosureParamIllegalNullable */'],
113+
['/* testTypeUnionWithReference */'],
114+
['/* testTypeUnionWithSpreadOperator */'],
113115
['/* testTypeUnionClosureReturn */'],
114116
['/* testTypeUnionArrowParam */'],
115117
['/* testTypeUnionArrowReturnType */'],

0 commit comments

Comments
 (0)