Skip to content

Commit

Permalink
Merge pull request #471 from PHPCSStandards/php-8.2/file-getmethodpar…
Browse files Browse the repository at this point in the history
…ameters-support-dnf

PHP 8.2 | File::getMethodParameters(): add support for DNF types
  • Loading branch information
jrfnl authored May 2, 2024
2 parents 7aceb91 + 36aa8aa commit f036e26
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 2 deletions.
6 changes: 5 additions & 1 deletion src/Files/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -1419,7 +1419,9 @@ public function getMethodParameters($stackPtr)
// it's likely to be an array which might have arguments in it. This
// could cause problems in our parsing below, so lets just skip to the
// end of it.
if (isset($this->tokens[$i]['parenthesis_opener']) === true) {
if ($this->tokens[$i]['code'] !== T_TYPE_OPEN_PARENTHESIS
&& isset($this->tokens[$i]['parenthesis_opener']) === true
) {
// Don't do this if it's the close parenthesis for the method.
if ($i !== $this->tokens[$i]['parenthesis_closer']) {
$i = $this->tokens[$i]['parenthesis_closer'];
Expand Down Expand Up @@ -1513,6 +1515,8 @@ public function getMethodParameters($stackPtr)
case T_NS_SEPARATOR:
case T_TYPE_UNION:
case T_TYPE_INTERSECTION:
case T_TYPE_OPEN_PARENTHESIS:
case T_TYPE_CLOSE_PARENTHESIS:
case T_FALSE:
case T_TRUE:
case T_NULL:
Expand Down
17 changes: 17 additions & 0 deletions tests/Core/File/GetMethodParametersTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,23 @@ function newInInitializers(
\Package\TypeB $newToo = new \Package\TypeB(10, 'string'),
) {}

/* testPHP82DNFTypes */
function dnfTypes(
#[MyAttribute]
false|(Foo&Bar)|true $obj1,
(\Boo&\Pck\Bar)|(Boo&Baz) $obj2 = new Boo()
) {}

/* testPHP82DNFTypesWithSpreadOperatorAndReference */
function dnfInGlobalFunctionWithSpreadAndReference((Countable&MeMe)|iterable &$paramA, true|(Foo&Bar) ...$paramB) {}

/* testPHP82DNFTypesIllegalNullable */
// Intentional fatal error - nullable operator cannot be combined with DNF.
$dnf_closure = function (? ( MyClassA & /*comment*/ \Package\MyClassB & \Package\MyClassC ) $var): void {};

/* testPHP82DNFTypesInArrow */
$dnf_arrow = fn((Hi&Ho)|FALSE &...$range): string => $a;

/* testFunctionCallFnPHPCS353-354 */
$value = $obj->fn(true);

Expand Down
157 changes: 156 additions & 1 deletion tests/Core/File/GetMethodParametersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2450,7 +2450,7 @@ public function testPHP8IntersectionTypes()


/**
* Verify recognition of PHP8 intersection type declaration when the variable
* Verify recognition of PHP8.1 intersection type declaration when the variable
* has either a spread operator or a reference.
*
* @return void
Expand Down Expand Up @@ -2702,6 +2702,161 @@ public function testPHP81NewInInitializers()
}//end testPHP81NewInInitializers()


/**
* Verify recognition of 8.2 DNF parameter type declarations.
*
* @return void
*/
public function testPHP82DNFTypes()
{
// Offsets are relative to the T_FUNCTION token.
$expected = [];
$expected[0] = [
'token' => 21,
'name' => '$obj1',
'content' => '#[MyAttribute]
false|(Foo&Bar)|true $obj1',
'has_attributes' => true,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => 'false|(Foo&Bar)|true',
'type_hint_token' => 11,
'type_hint_end_token' => 19,
'nullable_type' => false,
'comma_token' => 22,
];
$expected[1] = [
'token' => 41,
'name' => '$obj2',
'content' => '(\Boo&\Pck\Bar)|(Boo&Baz) $obj2 = new Boo()',
'default' => 'new Boo()',
'default_token' => 45,
'default_equal_token' => 43,
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => '(\Boo&\Pck\Bar)|(Boo&Baz)',
'type_hint_token' => 25,
'type_hint_end_token' => 39,
'nullable_type' => false,
'comma_token' => false,
];

$this->getMethodParametersTestHelper('/* '.__FUNCTION__.' */', $expected);

}//end testPHP82DNFTypes()


/**
* Verify recognition of PHP 8.2 DNF parameter type declarations when the variable
* has either a spread operator or a reference.
*
* @return void
*/
public function testPHP82DNFTypesWithSpreadOperatorAndReference()
{
// Offsets are relative to the T_FUNCTION token.
$expected = [];
$expected[0] = [
'token' => 13,
'name' => '$paramA',
'content' => '(Countable&MeMe)|iterable &$paramA',
'has_attributes' => false,
'pass_by_reference' => true,
'reference_token' => 12,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => '(Countable&MeMe)|iterable',
'type_hint_token' => 4,
'type_hint_end_token' => 10,
'nullable_type' => false,
'comma_token' => 14,
];
$expected[1] = [
'token' => 25,
'name' => '$paramB',
'content' => 'true|(Foo&Bar) ...$paramB',
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => true,
'variadic_token' => 24,
'type_hint' => 'true|(Foo&Bar)',
'type_hint_token' => 16,
'type_hint_end_token' => 22,
'nullable_type' => false,
'comma_token' => false,
];

$this->getMethodParametersTestHelper('/* '.__FUNCTION__.' */', $expected);

}//end testPHP82DNFTypesWithSpreadOperatorAndReference()


/**
* Verify recognition of PHP 8.2 DNF parameter type declarations using the nullability operator (not allowed).
*
* @return void
*/
public function testPHP82DNFTypesIllegalNullable()
{
// Offsets are relative to the T_FUNCTION token.
$expected = [];
$expected[0] = [
'token' => 27,
'name' => '$var',
'content' => '? ( MyClassA & /*comment*/ \Package\MyClassB & \Package\MyClassC ) $var',
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => '?(MyClassA&\Package\MyClassB&\Package\MyClassC)',
'type_hint_token' => 5,
'type_hint_end_token' => 25,
'nullable_type' => true,
'comma_token' => false,
];

$this->getMethodParametersTestHelper('/* '.__FUNCTION__.' */', $expected);

}//end testPHP82DNFTypesIllegalNullable()


/**
* Verify recognition of PHP 8.2 DNF parameter type declarations in an arrow function.
*
* @return void
*/
public function testPHP82DNFTypesInArrow()
{
// Offsets are relative to the T_FUNCTION token.
$expected = [];
$expected[0] = [
'token' => 12,
'name' => '$range',
'content' => '(Hi&Ho)|FALSE &...$range',
'has_attributes' => false,
'pass_by_reference' => true,
'reference_token' => 10,
'variable_length' => true,
'variadic_token' => 11,
'type_hint' => '(Hi&Ho)|FALSE',
'type_hint_token' => 2,
'type_hint_end_token' => 8,
'nullable_type' => false,
'comma_token' => false,
];

$this->getMethodParametersTestHelper('/* '.__FUNCTION__.' */', $expected);

}//end testPHP82DNFTypesInArrow()


/**
* Verify handling of a closure.
*
Expand Down

0 comments on commit f036e26

Please sign in to comment.