Skip to content

Commit

Permalink
WAIT UPSTREAM 3662 + requires PHPCS version bump (or polyfill) | PHP …
Browse files Browse the repository at this point in the history
…8.2 | BCFile::getMethodProperties(): sync with upstream / add support for true pseudotype

As pulled in upstream PR 3662 (not yet merged).

Includes unit tests.

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

Refs:
* squizlabs/PHP_CodeSniffer 3662
* PHPCSStandards/PHPCSUtils 368
  • Loading branch information
jrfnl committed Dec 7, 2023
1 parent 56dc191 commit 68c62c1
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 62 deletions.
7 changes: 0 additions & 7 deletions PHPCSUtils/Utils/FunctionDeclarations.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,6 @@ public static function getName(File $phpcsFile, $stackPtr)
* - Defensive coding against incorrect calls to this method.
* - More efficient checking whether a function has a body.
* - Support for PHP 8.0 identifier name tokens in return 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::getMethodProperties() Original source.
Expand Down Expand Up @@ -248,12 +247,6 @@ public static function getProperties(File $phpcsFile, $stackPtr)
$hasBody = false;
$returnTypeTokens = Collections::returnTypeTokens();

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

$parenthesisCloser = null;
if (isset($tokens[$stackPtr]['parenthesis_closer']) === true) {
$parenthesisCloser = $tokens[$stackPtr]['parenthesis_closer'];
Expand Down
11 changes: 9 additions & 2 deletions Tests/BackCompat/BCFile/GetMethodPropertiesTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ function unionTypesAllPseudoTypes($var) : false|MIXED|self|parent|static|iterabl
$closure = function () use($a) :?int|float {};

/* 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 {}

/* 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 {}

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

/* testPHP82PseudoTypeTrue */
function pseudoTypeTrue(): ?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 {}

/* testNotAFunction */
return true;

Expand Down
46 changes: 46 additions & 0 deletions Tests/BackCompat/BCFile/GetMethodPropertiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,52 @@ public function testPHP81NullableIntersectionTypes()
$this->getMethodPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected);
}

/**
* Verify recognition of PHP8.1 intersection type declaration with (illegal) nullability.
*
* @return void
*/
public function testPHP82PseudoTypeTrue()
{
$expected = [
'scope' => 'public',
'scope_specified' => false,
'return_type' => '?true',
'return_type_token' => 8, // Offset from the T_FUNCTION token.
'return_type_end_token' => 8, // Offset from the T_FUNCTION token.
'nullable_return_type' => true,
'is_abstract' => false,
'is_final' => false,
'is_static' => false,
'has_body' => true,
];

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

/**
* Verify recognition of PHP8.1 intersection type declaration with (illegal) nullability.
*
* @return void
*/
public function testPHP82PseudoTypeFalseAndTrue()
{
$expected = [
'scope' => 'public',
'scope_specified' => false,
'return_type' => 'true|false',
'return_type_token' => 7, // Offset from the T_FUNCTION token.
'return_type_end_token' => 9, // Offset from the T_FUNCTION token.
'nullable_return_type' => false,
'is_abstract' => false,
'is_final' => false,
'is_static' => false,
'has_body' => true,
];

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

/**
* Test for incorrect tokenization of array return type declarations in PHPCS < 2.8.0.
*
Expand Down
7 changes: 0 additions & 7 deletions Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,3 @@ trait FooTrait {
$func();
}
}

/* testPHP82PseudoTypeTrue */
function pseudoTypeTrue(): ?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 {}
46 changes: 0 additions & 46 deletions Tests/Utils/FunctionDeclarations/GetPropertiesDiffTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,52 +88,6 @@ public function testMessyPhpcsAnnotationsStaticClosure()
$this->getPropertiesTestHelper('/* ' . __FUNCTION__ . ' */', $expected);
}

/**
* Verify recognition of PHP 8.2 stand-alone `true` type.
*
* @return void
*/
public function testPHP82PseudoTypeTrue()
{
$expected = [
'scope' => 'public',
'scope_specified' => false,
'return_type' => '?true',
'return_type_token' => 8, // Offset from the T_FUNCTION token.
'return_type_end_token' => 8, // Offset from the T_FUNCTION token.
'nullable_return_type' => true,
'is_abstract' => false,
'is_final' => false,
'is_static' => false,
'has_body' => true,
];

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

/**
* Verify recognition of PHP 8.2 type declaration with (illegal) type false combined with type true.
*
* @return void
*/
public function testPHP82PseudoTypeFalseAndTrue()
{
$expected = [
'scope' => 'public',
'scope_specified' => false,
'return_type' => 'true|false',
'return_type_token' => 7, // Offset from the T_FUNCTION token.
'return_type_end_token' => 9, // Offset from the T_FUNCTION token.
'nullable_return_type' => false,
'is_abstract' => false,
'is_final' => false,
'is_static' => false,
'has_body' => true,
];

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

/**
* Test helper.
*
Expand Down

0 comments on commit 68c62c1

Please sign in to comment.