Skip to content

Commit

Permalink
Merge pull request #78 from PHPCSStandards/feature/tokenizer-php-bugf…
Browse files Browse the repository at this point in the history
…ix-static-typed-props-union-intersection

Tokenizer/PHP: bug fix for static typed properties with union/intersection types
  • Loading branch information
jrfnl authored Dec 4, 2023
2 parents c1cf656 + 6a3b638 commit 334a64f
Show file tree
Hide file tree
Showing 8 changed files with 18 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ The file documents changes to the PHP_CodeSniffer project.
- Thanks to Dan Wallis (@fredden) for the patch
- Fixed bug #3816 : PSR12/FileHeader: bug fix - false positives on PHP 8.2+ readonly classes
- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch
- Fixed bug #3867 : Tokenizer/PHP: union type and intersection type operators were not correctly tokenized for static properties without explicit visibility
- Thanks to Juliette Reinders Folmer (@jrfnl) for the patch
- Fixed bug #3877 : Filter names can be case-sensitive. The -h help text will now display the correct case for the available filters
- Thanks to @simonsan for the patch
- Fixed bug #3906 : Tokenizer/CSS: fixed a bug related to the unsupported slash comment syntax
Expand Down
5 changes: 5 additions & 0 deletions src/Tokenizers/PHP.php
Original file line number Diff line number Diff line change
Expand Up @@ -2998,6 +2998,10 @@ protected function processAdditional()
continue;
}

if ($suspectedType === 'property or parameter') {
unset($allowed[\T_STATIC]);
}

$typeTokenCount = 0;
$typeOperators = [$i];
$confirmed = false;
Expand Down Expand Up @@ -3030,6 +3034,7 @@ protected function processAdditional()
if ($suspectedType === 'property or parameter'
&& (isset(Util\Tokens::$scopeModifiers[$this->tokens[$x]['code']]) === true
|| $this->tokens[$x]['code'] === T_VAR
|| $this->tokens[$x]['code'] === T_STATIC
|| $this->tokens[$x]['code'] === T_READONLY)
) {
// This will also confirm constructor property promotion parameters, but that's fine.
Expand Down
3 changes: 2 additions & 1 deletion tests/Core/File/GetMemberPropertiesTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,8 @@ $anon = class() {

/* testPHP8UnionTypesIllegalTypes */
// Intentional fatal error - types which are not allowed for properties, but that's not the concern of the method.
public callable|static|void $unionTypesIllegalTypes;
// Note: static is also not allowed as a type, but using static for a property type is not supported by the tokenizer.
public callable|void $unionTypesIllegalTypes;

/* testPHP8UnionTypesNullable */
// Intentional fatal error - nullability is not allowed with union types, but that's not the concern of the method.
Expand Down
3 changes: 1 addition & 2 deletions tests/Core/File/GetMemberPropertiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -587,8 +587,7 @@ public function dataGetMemberProperties()
'scope_specified' => true,
'is_static' => false,
'is_readonly' => false,
// Missing static, but that's OK as not an allowed syntax.
'type' => 'callable||void',
'type' => 'callable|void',
'nullable_type' => false,
],
],
Expand Down
3 changes: 3 additions & 0 deletions tests/Core/Tokenizer/BitwiseOrTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class TypeUnion
/* testTypeUnionPropertyWithOnlyReadOnlyKeyword */
readonly string|null $nullableString;

/* testTypeUnionPropertyWithOnlyStaticKeyword */
static Foo|Bar $obj;

public function paramTypes(
/* testTypeUnionParam1 */
int|float $paramA /* testBitwiseOrParamDefaultValue */ = CONSTANT_A | CONSTANT_B,
Expand Down
1 change: 1 addition & 0 deletions tests/Core/Tokenizer/BitwiseOrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public function dataTypeUnion()
['/* testTypeUnionPropertyWithStaticAndReadOnlyKeywords */'],
['/* testTypeUnionPropertyWithVarAndReadOnlyKeywords */'],
['/* testTypeUnionPropertyWithOnlyReadOnlyKeyword */'],
['/* testTypeUnionPropertyWithOnlyStaticKeyword */'],
['/* testTypeUnionParam1 */'],
['/* testTypeUnionParam2 */'],
['/* testTypeUnionParam3 */'],
Expand Down
3 changes: 3 additions & 0 deletions tests/Core/Tokenizer/TypeIntersectionTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class TypeIntersection
/* testTypeIntersectionPropertyWithReadOnlyKeyword */
protected readonly Foo&Bar $fooBar;

/* testTypeIntersectionPropertyWithStaticKeyword */
static Foo&Bar $obj;

public function paramTypes(
/* testTypeIntersectionParam1 */
Foo&Bar $paramA /* testBitwiseAndParamDefaultValue */ = CONSTANT_A & CONSTANT_B,
Expand Down
1 change: 1 addition & 0 deletions tests/Core/Tokenizer/TypeIntersectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ public function dataTypeIntersection()
['/* testTypeIntersectionPropertyPartiallyQualified */'],
['/* testTypeIntersectionPropertyFullyQualified */'],
['/* testTypeIntersectionPropertyWithReadOnlyKeyword */'],
['/* testTypeIntersectionPropertyWithStaticKeyword */'],
['/* testTypeIntersectionParam1 */'],
['/* testTypeIntersectionParam2 */'],
['/* testTypeIntersectionParam3 */'],
Expand Down

0 comments on commit 334a64f

Please sign in to comment.