diff --git a/src/Tokenizers/PHP.php b/src/Tokenizers/PHP.php index c6b8e29065..85bf7402b0 100644 --- a/src/Tokenizers/PHP.php +++ b/src/Tokenizers/PHP.php @@ -3379,7 +3379,8 @@ protected function processAdditional() && (isset(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->tokens[$x]['code'] === T_READONLY + || $this->tokens[$x]['code'] === T_FINAL) ) { // This will also confirm constructor property promotion parameters, but that's fine. $confirmed = true; diff --git a/tests/Core/Tokenizers/PHP/BitwiseOrTest.inc b/tests/Core/Tokenizers/PHP/BitwiseOrTest.inc index 54ff50822c..c2c4508e43 100644 --- a/tests/Core/Tokenizers/PHP/BitwiseOrTest.inc +++ b/tests/Core/Tokenizers/PHP/BitwiseOrTest.inc @@ -75,6 +75,15 @@ class TypeUnion /* testTypeUnionPropertyWithOnlyStaticKeyword */ static Foo|Bar $obj; + /* testTypeUnionWithPHP84FinalKeyword */ + final int|string $finalKeywordA; + + /* testTypeUnionWithPHP84FinalKeywordFirst */ + final private float|null $finalKeywordB; + + /* testTypeUnionWithPHP84FinalKeywordAndFQN */ + final \MyClass|false $finalKeywordC; + public function paramTypes( /* testTypeUnionParam1 */ int|float $paramA /* testBitwiseOrParamDefaultValue */ = CONSTANT_A | CONSTANT_B, diff --git a/tests/Core/Tokenizers/PHP/BitwiseOrTest.php b/tests/Core/Tokenizers/PHP/BitwiseOrTest.php index 3c9fa50a6a..ee1ff84f2a 100644 --- a/tests/Core/Tokenizers/PHP/BitwiseOrTest.php +++ b/tests/Core/Tokenizers/PHP/BitwiseOrTest.php @@ -125,6 +125,9 @@ public static function dataTypeUnion() 'type for readonly property, reversed modifier order' => ['/* testTypeUnionPropertyWithReadOnlyKeywordFirst */'], 'type for readonly property, no visibility' => ['/* testTypeUnionPropertyWithOnlyReadOnlyKeyword */'], 'type for static property, no visibility' => ['/* testTypeUnionPropertyWithOnlyStaticKeyword */'], + 'type for final property, no visibility' => ['/* testTypeUnionWithPHP84FinalKeyword */'], + 'type for final property, reversed modifier order' => ['/* testTypeUnionWithPHP84FinalKeywordFirst */'], + 'type for final property, no visibility, FQN type' => ['/* testTypeUnionWithPHP84FinalKeywordAndFQN */'], 'type for method parameter' => ['/* testTypeUnionParam1 */'], 'type for method parameter, first in multi-union' => ['/* testTypeUnionParam2 */'], 'type for method parameter, last in multi-union' => ['/* testTypeUnionParam3 */'], diff --git a/tests/Core/Tokenizers/PHP/DNFTypesTest.inc b/tests/Core/Tokenizers/PHP/DNFTypesTest.inc index cd27474eb2..c1a38c79e5 100644 --- a/tests/Core/Tokenizers/PHP/DNFTypesTest.inc +++ b/tests/Core/Tokenizers/PHP/DNFTypesTest.inc @@ -175,6 +175,12 @@ abstract class DNFTypes { /* testDNFTypePropertyWithOnlyStaticKeyword */ static (A&B&C)|true $onlyStaticModified; + /* testDNFTypeWithPHP84FinalKeyword */ + final (className&InterfaceName)|false $finalKeywordA; + + /* testDNFTypeWithPHP84FinalKeywordAndStatic */ + final static (\className&\InterfaceName)|false $finalKeywordB; + public function paramTypes( /* testDNFTypeParam1WithAttribute */ #[MyAttribute] diff --git a/tests/Core/Tokenizers/PHP/DNFTypesTest.php b/tests/Core/Tokenizers/PHP/DNFTypesTest.php index 4d80c4c5a7..3c9fcb80bc 100644 --- a/tests/Core/Tokenizers/PHP/DNFTypesTest.php +++ b/tests/Core/Tokenizers/PHP/DNFTypesTest.php @@ -432,7 +432,6 @@ public static function dataDNFTypeParentheses() 'OO property type: multi-dnf fully qualified classes' => [ 'testMarker' => '/* testDNFTypePropertyMultiFullyQualified */', ], - 'OO property type: multi-dnf with readonly keyword 1' => [ 'testMarker' => '/* testDNFTypePropertyWithReadOnlyKeyword1 */', ], @@ -445,6 +444,13 @@ public static function dataDNFTypeParentheses() 'OO property type: with only static keyword' => [ 'testMarker' => '/* testDNFTypePropertyWithOnlyStaticKeyword */', ], + 'OO property type: with only final keyword' => [ + 'testMarker' => '/* testDNFTypeWithPHP84FinalKeyword */', + ], + 'OO property type: with final and static keyword' => [ + 'testMarker' => '/* testDNFTypeWithPHP84FinalKeywordAndStatic */', + ], + 'OO method param type: first param' => [ 'testMarker' => '/* testDNFTypeParam1WithAttribute */', ], diff --git a/tests/Core/Tokenizers/PHP/TypeIntersectionTest.inc b/tests/Core/Tokenizers/PHP/TypeIntersectionTest.inc index 53177a5317..fadc0df85a 100644 --- a/tests/Core/Tokenizers/PHP/TypeIntersectionTest.inc +++ b/tests/Core/Tokenizers/PHP/TypeIntersectionTest.inc @@ -63,6 +63,12 @@ class TypeIntersection /* testTypeIntersectionPropertyWithStaticKeyword */ static Foo&Bar $obj; + /* testTypeIntersectionWithPHP84FinalKeyword */ + final className&InterfaceName $finalKeywordA; + + /* testTypeIntersectionWithPHP84FinalKeywordFirst */ + final private \className&InterfaceName $finalKeywordB; + public function paramTypes( /* testTypeIntersectionParam1 */ Foo&Bar $paramA /* testBitwiseAndParamDefaultValue */ = CONSTANT_A & CONSTANT_B, diff --git a/tests/Core/Tokenizers/PHP/TypeIntersectionTest.php b/tests/Core/Tokenizers/PHP/TypeIntersectionTest.php index 8ed951de85..b191d7ebd4 100644 --- a/tests/Core/Tokenizers/PHP/TypeIntersectionTest.php +++ b/tests/Core/Tokenizers/PHP/TypeIntersectionTest.php @@ -124,6 +124,8 @@ public static function dataTypeIntersection() 'type for property using fully qualified names' => ['/* testTypeIntersectionPropertyFullyQualified */'], 'type for readonly property' => ['/* testTypeIntersectionPropertyWithReadOnlyKeyword */'], 'type for static readonly property' => ['/* testTypeIntersectionPropertyWithStaticKeyword */'], + 'type for final property' => ['/* testTypeIntersectionWithPHP84FinalKeyword */'], + 'type for final property reversed modifier order' => ['/* testTypeIntersectionWithPHP84FinalKeywordFirst */'], 'type for method parameter' => ['/* testTypeIntersectionParam1 */'], 'type for method parameter, first in multi-intersect' => ['/* testTypeIntersectionParam2 */'], 'type for method parameter, last in multi-intersect' => ['/* testTypeIntersectionParam3 */'],