Skip to content

Commit

Permalink
PHP 8.2 | BCFile::getMethodParameters(): sync with upstream / add sup…
Browse files Browse the repository at this point in the history
…port for true pseudotype

As pulled in upstream PR squizlabs/PHP_CodeSniffer3662 / PHPCSStandards/PHP_CodeSniffer 49.

Includes unit tests.

Support for the `true` type was previously already added to the `FunctionDeclarations::getParameters()` method in PR 368.

Refs:
* squizlabs/PHP_CodeSniffer 3662
* PHPCSStandards/PHP_CodeSniffer 49
* PHPCSStandards/PHPCSUtils 368
  • Loading branch information
jrfnl committed Dec 7, 2023
1 parent 2da8f0b commit df1458a
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 91 deletions.
7 changes: 0 additions & 7 deletions PHPCSUtils/Utils/FunctionDeclarations.php
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,6 @@ public static function getProperties(File $phpcsFile, $stackPtr)
* - More efficient and more stable looping of the default value.
* - Clearer exception message when a non-closure use token was passed to the function.
* - Support for PHP 8.0 identifier name tokens in parameter types, cross-version PHP & PHPCS.
* - Support for the PHP 8.2 `true` type.
* - The results of this function call are cached during a PHPCS run for faster response times.
*
* @see \PHP_CodeSniffer\Files\File::getMethodParameters() Original source.
Expand Down Expand Up @@ -440,12 +439,6 @@ public static function getParameters(File $phpcsFile, $stackPtr)

$parameterTypeTokens = Collections::parameterTypeTokens();

/*
* BC PHPCS < 3.x.x: The union type separator is not (yet) retokenized correctly
* for union types containing the `true` type.
*/
$parameterTypeTokens[\T_BITWISE_OR] = \T_BITWISE_OR;

for ($i = $paramStart; $i <= $closer; $i++) {
if (isset($parameterTypeTokens[$tokens[$i]['code']]) === true
/*
Expand Down
11 changes: 9 additions & 2 deletions Tests/BackCompat/BCFile/GetMethodParametersTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@ function unionTypesAllPseudoTypes(false|mixed|self|parent|iterable|Resource $var
$closure = function (?int|float $number) {};

/* testPHP8PseudoTypeNull */
// Intentional fatal error - null pseudotype is only allowed in union types, but that's not the concern of the method.
// PHP 8.0 - 8.1: Intentional fatal error - null pseudotype is only allowed in union types, but that's not the concern of the method.
function pseudoTypeNull(null $var = null) {}

/* testPHP8PseudoTypeFalse */
// Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method.
// PHP 8.0 - 8.1: Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method.
function pseudoTypeFalse(false $var = false) {}

/* testPHP8PseudoTypeFalseAndBool */
Expand Down Expand Up @@ -267,6 +267,13 @@ $closure = function (string&int $numeric_string) {};
// Intentional fatal error - nullability is not allowed with intersection types, but that's not the concern of the method.
$closure = function (?Foo&Bar $object) {};

/* testPHP82PseudoTypeTrue */
function pseudoTypeTrue(?true $var = true) {}

/* testPHP82PseudoTypeFalseAndTrue */
// Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method.
function pseudoTypeFalseAndTrue(true|false $var = true) {}

/* testPHP81NewInInitializers */
function newInInitializers(
TypeA $new = new TypeA(self::CONST_VALUE),
Expand Down
60 changes: 60 additions & 0 deletions Tests/BackCompat/BCFile/GetMethodParametersTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2436,6 +2436,66 @@ public function testPHP81NullableIntersectionTypes()
$this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected);
}

/**
* Verify recognition of PHP 8.2 stand-alone `true` type.
*
* @return void
*/
public function testPHP82PseudoTypeTrue()
{
$expected = [];
$expected[0] = [
'token' => 7, // Offset from the T_FUNCTION token.
'name' => '$var',
'content' => '?true $var = true',
'default' => 'true',
'default_token' => 11, // Offset from the T_FUNCTION token.
'default_equal_token' => 9, // Offset from the T_FUNCTION token.
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => '?true',
'type_hint_token' => 5, // Offset from the T_FUNCTION token.
'type_hint_end_token' => 5, // Offset from the T_FUNCTION token.
'nullable_type' => true,
'comma_token' => false,
];

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

/**
* Verify recognition of PHP 8.2 type declaration with (illegal) type false combined with type true.
*
* @return void
*/
public function testPHP82PseudoTypeFalseAndTrue()
{
$expected = [];
$expected[0] = [
'token' => 8, // Offset from the T_FUNCTION token.
'name' => '$var',
'content' => 'true|false $var = true',
'default' => 'true',
'default_token' => 12, // Offset from the T_FUNCTION token.
'default_equal_token' => 10, // Offset from the T_FUNCTION token.
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => 'true|false',
'type_hint_token' => 4, // Offset from the T_FUNCTION token.
'type_hint_end_token' => 6, // Offset from the T_FUNCTION token.
'nullable_type' => false,
'comma_token' => false,
];

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

/**
* Verify behaviour when the default value uses the "new" keyword, as is allowed per PHP 8.1.
*
Expand Down
8 changes: 0 additions & 8 deletions Tests/Utils/FunctionDeclarations/GetParametersDiffTest.inc

This file was deleted.

83 changes: 9 additions & 74 deletions Tests/Utils/FunctionDeclarations/GetParametersDiffTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,94 +31,29 @@ final class GetParametersDiffTest extends UtilityMethodTestCase
{

/**
* Test passing a non-existent token pointer.
* Initialize PHPCS & tokenize the test case file.
*
* @return void
*/
public function testNonExistentToken()
{
$this->expectPhpcsException('$stackPtr must be of type T_FUNCTION, T_CLOSURE or T_USE or an arrow function');

FunctionDeclarations::getParameters(self::$phpcsFile, 10000);
}

/**
* Verify recognition of PHP 8.2 stand-alone `true` type.
* @beforeClass
*
* @return void
*/
public function testPHP82PseudoTypeTrue()
public static function setUpTestFile()
{
$expected = [];
$expected[0] = [
'token' => 7, // Offset from the T_FUNCTION token.
'name' => '$var',
'content' => '?true $var = true',
'default' => 'true',
'default_token' => 11, // Offset from the T_FUNCTION token.
'default_equal_token' => 9, // Offset from the T_FUNCTION token.
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => '?true',
'type_hint_token' => 5, // Offset from the T_FUNCTION token.
'type_hint_end_token' => 5, // Offset from the T_FUNCTION token.
'nullable_type' => true,
'comma_token' => false,
];

$this->getMethodParametersTestHelper('/* ' . __FUNCTION__ . ' */', $expected);
self::$caseFile = \dirname(\dirname(__DIR__)) . '/DummyFile.inc';
parent::setUpTestFile();
}

/**
* Verify recognition of PHP 8.2 type declaration with (illegal) type false combined with type true.
*
* @return void
*/
public function testPHP82PseudoTypeFalseAndTrue()
{
$expected = [];
$expected[0] = [
'token' => 8, // Offset from the T_FUNCTION token.
'name' => '$var',
'content' => 'true|false $var = true',
'default' => 'true',
'default_token' => 12, // Offset from the T_FUNCTION token.
'default_equal_token' => 10, // Offset from the T_FUNCTION token.
'has_attributes' => false,
'pass_by_reference' => false,
'reference_token' => false,
'variable_length' => false,
'variadic_token' => false,
'type_hint' => 'true|false',
'type_hint_token' => 4, // Offset from the T_FUNCTION token.
'type_hint_end_token' => 6, // Offset from the T_FUNCTION token.
'nullable_type' => false,
'comma_token' => false,
];

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

/**
* Test helper.
*
* @param string $marker The comment which preceeds the test.
* @param array $expected The expected function output.
* @param array $targetType Optional. The token type to search for after $marker.
* Defaults to the function/closure/arrow tokens.
* Test passing a non-existent token pointer.
*
* @return void
*/
protected function getMethodParametersTestHelper($marker, $expected, $targetType = [\T_FUNCTION, \T_CLOSURE, \T_FN])
public function testNonExistentToken()
{
$target = $this->getTargetToken($marker, $targetType);
$found = FunctionDeclarations::getParameters(self::$phpcsFile, $target);
$this->expectPhpcsException('$stackPtr must be of type T_FUNCTION, T_CLOSURE or T_USE or an arrow function');
$expected = $this->updateExpectedTokenPositions($target, $expected);

Check failure on line 54 in Tests/Utils/FunctionDeclarations/GetParametersDiffTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Undefined variable: $expected

Check failure on line 54 in Tests/Utils/FunctionDeclarations/GetParametersDiffTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Undefined variable: $target

Check failure on line 54 in Tests/Utils/FunctionDeclarations/GetParametersDiffTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Undefined variable: $expected

Check failure on line 54 in Tests/Utils/FunctionDeclarations/GetParametersDiffTest.php

View workflow job for this annotation

GitHub Actions / PHPStan

Undefined variable: $target

$this->assertSame($expected, $found);
FunctionDeclarations::getParameters(self::$phpcsFile, 10000);
}

/**
Expand Down

0 comments on commit df1458a

Please sign in to comment.