diff --git a/src/Tokenizers/PHP.php b/src/Tokenizers/PHP.php index 2fdabbfdab..a00c918ddf 100644 --- a/src/Tokenizers/PHP.php +++ b/src/Tokenizers/PHP.php @@ -3499,7 +3499,8 @@ protected function processAdditional() || $this->tokens[$x]['code'] === T_VAR || $this->tokens[$x]['code'] === T_STATIC || $this->tokens[$x]['code'] === T_READONLY - || $this->tokens[$x]['code'] === T_FINAL) + || $this->tokens[$x]['code'] === T_FINAL + || $this->tokens[$x]['code'] === T_ABSTRACT) ) { // 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 822b4413c4..6e7d58890d 100644 --- a/tests/Core/Tokenizers/PHP/BitwiseOrTest.inc +++ b/tests/Core/Tokenizers/PHP/BitwiseOrTest.inc @@ -7,7 +7,7 @@ /* testBitwiseOr1 */ $result = $value | $test /* testBitwiseOr2 */ | $another; -class TypeUnion +abstract class TypeUnion { /* testTypeUnionOOConstSimple */ public const Foo|Bar SIMPLE = new Foo; @@ -96,6 +96,15 @@ class TypeUnion /* testTypeUnionPropertyPublicProtected */ public protected(set) Foo|Bar $asym4; + /* testTypeUnionWithPHP84AbstractKeyword */ + abstract int|string $abstractKeywordA { get; } + + /* testTypeUnionWithPHP84AbstractKeywordFirst */ + abstract protected float|null $abstractKeywordB { set; } + + /* testTypeUnionWithPHP84AbstractKeywordAndFQN */ + abstract \MyClass|false $abstractKeywordC { get; } + 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 bfe409aed5..17febdc453 100644 --- a/tests/Core/Tokenizers/PHP/BitwiseOrTest.php +++ b/tests/Core/Tokenizers/PHP/BitwiseOrTest.php @@ -132,6 +132,9 @@ public static function dataTypeUnion() 'type for public private(set) property' => ['/* testTypeUnionPropertyPublicPrivateSet */'], 'type for protected(set) property' => ['/* testTypeUnionPropertyProtected */'], 'type for public protected(set) property' => ['/* testTypeUnionPropertyPublicProtected */'], + 'type for abstract property, no visibility' => ['/* testTypeUnionWithPHP84AbstractKeyword */'], + 'type for abstract property, reversed modifier order' => ['/* testTypeUnionWithPHP84AbstractKeywordFirst */'], + 'type for abstract property, no visibility, FQN type' => ['/* testTypeUnionWithPHP84AbstractKeywordAndFQN */'], '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 ae9dc94488..877d57ed9d 100644 --- a/tests/Core/Tokenizers/PHP/DNFTypesTest.inc +++ b/tests/Core/Tokenizers/PHP/DNFTypesTest.inc @@ -193,6 +193,12 @@ abstract class DNFTypes { /* testDNFTypePropertyWithPublicProtectedSet */ public protected(set) (A&B&C)|true $asym4; + /* testDNFTypeWithPHP84AbstractKeyword */ + abstract (className&InterfaceName)|false $abstractKeywordA { set; } + + /* testDNFTypeWithPHP84AbstractKeywordAndPublic */ + abstract public (\className&\InterfaceName)|false $abstractKeywordB { get; } + public function paramTypes( /* testDNFTypeParam1WithAttribute */ #[MyAttribute] diff --git a/tests/Core/Tokenizers/PHP/DNFTypesTest.php b/tests/Core/Tokenizers/PHP/DNFTypesTest.php index 5ef220ec79..312df1b378 100644 --- a/tests/Core/Tokenizers/PHP/DNFTypesTest.php +++ b/tests/Core/Tokenizers/PHP/DNFTypesTest.php @@ -462,6 +462,13 @@ public static function dataDNFTypeParentheses() 'OO property type: asymmetric vis, public protected(set)' => [ 'testMarker' => '/* testDNFTypePropertyWithPublicProtectedSet */', ], + 'OO property type: with only abstract keyword' => [ + 'testMarker' => '/* testDNFTypeWithPHP84AbstractKeyword */', + ], + 'OO property type: with abstract and public keyword' => [ + 'testMarker' => '/* testDNFTypeWithPHP84AbstractKeywordAndPublic */', + ], + 'OO method param type: first param' => [ 'testMarker' => '/* testDNFTypeParam1WithAttribute */', ], diff --git a/tests/Core/Tokenizers/PHP/NullableVsInlineThenTest.inc b/tests/Core/Tokenizers/PHP/NullableVsInlineThenTest.inc index 56ad3856c3..ce25391203 100644 --- a/tests/Core/Tokenizers/PHP/NullableVsInlineThenTest.inc +++ b/tests/Core/Tokenizers/PHP/NullableVsInlineThenTest.inc @@ -1,6 +1,6 @@ ['/* testNullableReadonlyOnly */'], 'property declaration, private set' => ['/* testNullablePrivateSet */'], 'property declaration, public and protected set' => ['/* testNullablePublicProtectedSet */'], + 'property declaration, final, no visibility' => ['/* testNullableFinalOnly */'], + 'property declaration, abstract, no visibility' => ['/* testNullableAbstractOnly */'], ]; }//end dataNullable() /** - * Test that "readonly" when not used as the keyword is still tokenized as `T_STRING`. + * Test that a "?" when used as part of a ternary expression is tokenized as `T_INLINE_THEN`. * * @param string $testMarker The comment which prefaces the target token in the test file. * diff --git a/tests/Core/Tokenizers/PHP/TypeIntersectionTest.inc b/tests/Core/Tokenizers/PHP/TypeIntersectionTest.inc index 54b3c06e19..c5792d6c68 100644 --- a/tests/Core/Tokenizers/PHP/TypeIntersectionTest.inc +++ b/tests/Core/Tokenizers/PHP/TypeIntersectionTest.inc @@ -7,7 +7,7 @@ /* testBitwiseAnd1 */ $result = $value & $test /* testBitwiseAnd2 */ & $another; -class TypeIntersection +abstract class TypeIntersection { /* testTypeIntersectionOOConstSimple */ public const Foo&Bar SIMPLE = new Foo(); @@ -81,6 +81,12 @@ class TypeIntersection /* testTypeIntersectionPropertyWithPublicProtectedSet */ public protected(set) Foo&Bar $asym4; + /* testTypeIntersectionWithPHP84AbstractKeyword */ + abstract className&InterfaceName $abstractKeywordA { get; } + + /* testTypeIntersectionWithPHP84AbstractKeywordFirst */ + abstract protected \className&InterfaceName $abstractKeywordB { set; } + 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 3a4eb0070c..210a106d6c 100644 --- a/tests/Core/Tokenizers/PHP/TypeIntersectionTest.php +++ b/tests/Core/Tokenizers/PHP/TypeIntersectionTest.php @@ -130,6 +130,8 @@ public static function dataTypeIntersection() 'type for asymmetric visibility (public private(set)) prop' => ['/* testTypeIntersectionPropertyWithPublicPrivateSet */'], 'type for asymmetric visibility (protected(set)) property' => ['/* testTypeIntersectionPropertyWithProtectedSet */'], 'type for asymmetric visibility (public protected(set)) prop' => ['/* testTypeIntersectionPropertyWithPublicProtectedSet */'], + 'type for abstract property' => ['/* testTypeIntersectionWithPHP84AbstractKeyword */'], + 'type for abstract property reversed modifier order' => ['/* testTypeIntersectionWithPHP84AbstractKeywordFirst */'], 'type for method parameter' => ['/* testTypeIntersectionParam1 */'], 'type for method parameter, first in multi-intersect' => ['/* testTypeIntersectionParam2 */'], 'type for method parameter, last in multi-intersect' => ['/* testTypeIntersectionParam3 */'],