Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP 8.2 | BCFile::get*() methods: sync with upstream / add support for true pseudotype #524

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions PHPCSUtils/BackCompat/BCFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ public static function getMethodParameters(File $phpcsFile, $stackPtr)
case T_TYPE_UNION:
case T_TYPE_INTERSECTION:
case T_FALSE:
case T_TRUE:
case T_NULL:
// Part of a type hint or default value.
if ($defaultStart === null) {
Expand Down
14 changes: 0 additions & 14 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 Expand Up @@ -367,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 @@ -447,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
7 changes: 0 additions & 7 deletions PHPCSUtils/Utils/Variables.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ final class Variables
* other non-property variables passed to the method.
* - Defensive coding against incorrect calls to this method.
* - Support PHP 8.0 identifier name tokens in property 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::getMemberProperties() Original source.
Expand Down Expand Up @@ -183,12 +182,6 @@ public static function getMemberProperties(File $phpcsFile, $stackPtr)
$nullableType = false;
$propertyTypeTokens = Collections::propertyTypeTokens();

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

if ($i < $stackPtr) {
// We've found a type.
for ($i; $i < $stackPtr; $i++) {
Expand Down
19 changes: 17 additions & 2 deletions Tests/BackCompat/BCFile/GetMemberPropertiesTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,11 @@ $anon = class() {
public ?int|float $unionTypesNullable;

/* 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.
public null $pseudoTypeNull;

/* 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.
public false $pseudoTypeFalse;

/* testPHP8PseudoTypeFalseAndBool */
Expand Down Expand Up @@ -316,6 +316,21 @@ $anon = class() {
public ?Foo&Bar $nullableIntersectionType;
};

$anon = class() {
/* testPHP82PseudoTypeTrue */
public true $pseudoTypeTrue;

/* testPHP82NullablePseudoTypeTrue */
static protected ?true $pseudoTypeNullableTrue;

/* testPHP82PseudoTypeTrueInUnion */
private int|string|true $pseudoTypeTrueInUnion;

/* testPHP82PseudoTypeFalseAndTrue */
// Intentional fatal error - Type contains both true and false, bool should be used instead, but that's not the concern of the method.
readonly true|FALSE $pseudoTypeFalseAndTrue;
};

class WhitespaceAndCommentsInTypes {
/* testUnionTypeWithWhitespaceAndComment */
public int | /*comment*/ string $hasWhitespaceAndComment;
Expand Down
54 changes: 53 additions & 1 deletion Tests/BackCompat/BCFile/GetMemberPropertiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ public static function dataGetMemberProperties()
'is_static' => false,
'is_readonly' => false,
// Missing static, but that's OK as not an allowed syntax.
'type' => 'callable||void',
'type' => 'callable|void',
'type_token' => -6, // Offset from the T_VARIABLE token.
'type_end_token' => -2, // Offset from the T_VARIABLE token.
'nullable_type' => false,
Expand Down Expand Up @@ -1044,6 +1044,58 @@ public static function dataGetMemberProperties()
'nullable_type' => false,
],
],
'php8.2-pseudo-type-true' => [
'/* testPHP82PseudoTypeTrue */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'is_readonly' => false,
'type' => 'true',
'type_token' => -2, // Offset from the T_VARIABLE token.
'type_end_token' => -2, // Offset from the T_VARIABLE token.
'nullable_type' => false,
],
],
'php8.2-pseudo-type-true-nullable' => [
'/* testPHP82NullablePseudoTypeTrue */',
[
'scope' => 'protected',
'scope_specified' => true,
'is_static' => true,
'is_readonly' => false,
'type' => '?true',
'type_token' => -2, // Offset from the T_VARIABLE token.
'type_end_token' => -2, // Offset from the T_VARIABLE token.
'nullable_type' => true,
],
],
'php8.2-pseudo-type-true-in-union' => [
'/* testPHP82PseudoTypeTrueInUnion */',
[
'scope' => 'private',
'scope_specified' => true,
'is_static' => false,
'is_readonly' => false,
'type' => 'int|string|true',
'type_token' => -6, // Offset from the T_VARIABLE token.
'type_end_token' => -2, // Offset from the T_VARIABLE token.
'nullable_type' => false,
],
],
'php8.2-pseudo-type-invalid-true-false-union' => [
'/* testPHP82PseudoTypeFalseAndTrue */',
[
'scope' => 'public',
'scope_specified' => false,
'is_static' => false,
'is_readonly' => true,
'type' => 'true|FALSE',
'type_token' => -4, // Offset from the T_VARIABLE token.
'type_end_token' => -2, // Offset from the T_VARIABLE token.
'nullable_type' => false,
],
],
];
}

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
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
8 changes: 0 additions & 8 deletions Tests/Utils/FunctionDeclarations/GetParametersDiffTest.inc

This file was deleted.

Loading