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.0 | File::getMemberProperties(): support mixed type and union types #3011

Closed
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
6 changes: 5 additions & 1 deletion src/Files/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -1698,7 +1698,8 @@ public function getMethodProperties($stackPtr)
* // or FALSE if there is no type.
* 'type_end_token' => integer, // The stack pointer to the end of the type
* // or FALSE if there is no type.
* 'nullable_type' => boolean, // TRUE if the type is nullable.
* 'nullable_type' => boolean, // TRUE if the type is preceded by the nullability
* // operator.
* );
* </code>
*
Expand Down Expand Up @@ -1813,7 +1814,10 @@ public function getMemberProperties($stackPtr)
T_CALLABLE => T_CALLABLE,
T_SELF => T_SELF,
T_PARENT => T_PARENT,
T_FALSE => T_FALSE,
T_NULL => T_NULL,
T_NS_SEPARATOR => T_NS_SEPARATOR,
T_BITWISE_OR => T_BITWISE_OR,
];

for ($i; $i < $stackPtr; $i++) {
Expand Down
56 changes: 56 additions & 0 deletions tests/Core/File/GetMemberPropertiesTest.inc
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,59 @@ function_call( 'param', new class {
/* testNestedMethodParam 2 */
public function __construct( $open, $post_id ) {}
}, 10, 2 );

class PHP8Mixed {
/* testPHP8MixedTypeHint */
public static miXed $mixed;

/* testPHP8MixedTypeHintNullable */
// Intentional fatal error - nullability is not allowed with mixed, but that's not the concern of the method.
private ?mixed $nullableMixed;
}

$anon = class() {
/* testPHP8UnionTypesSimple */
public int|float $unionTypeSimple;

/* testPHP8UnionTypesTwoClasses */
private MyClassA|\Package\MyClassB $unionTypesTwoClasses;

/* testPHP8UnionTypesAllBaseTypes */
protected array|bool|int|float|NULL|object|string $unionTypesAllBaseTypes;

/* testPHP8UnionTypesAllPseudoTypes */
// Intentional fatal error - mixing types which cannot be combined, but that's not the concern of the method.
var false|mixed|self|parent|iterable|Resource $unionTypesAllPseudoTypes;

/* 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;

/* testPHP8UnionTypesNullable */
// Intentional fatal error - nullability is not allowed with union types, but that's not the concern of the method.
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.
public null $pseudoTypeNull;

/* testPHP8PseudoTypeFalse */
// Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method.
public false $pseudoTypeFalse;

/* testPHP8PseudoTypeFalseAndBool */
// Intentional fatal error - false pseudotype is not allowed in combination with bool, but that's not the concern of the method.
public bool|FALSE $pseudoTypeFalseAndBool;

/* testPHP8ObjectAndClass */
// Intentional fatal error - object is not allowed in combination with class name, but that's not the concern of the method.
public object|ClassName $objectAndClass;

/* testPHP8PseudoTypeIterableAndArray */
// Intentional fatal error - iterable pseudotype is not allowed in combination with array or Traversable, but that's not the concern of the method.
public iterable|array|Traversable $pseudoTypeIterableAndArray;

/* testPHP8DuplicateTypeInUnion */
// Intentional fatal error - duplicate types are not allowed in union types, but that's not the concern of the method.
public int|string|INT $duplicateTypeInUnion;
};
142 changes: 142 additions & 0 deletions tests/Core/File/GetMemberPropertiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,148 @@ public function dataGetMemberProperties()
'nullable_type' => false,
],
],
[
'/* testPHP8MixedTypeHint */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => true,
'type' => 'miXed',
'nullable_type' => false,
],
],
[
'/* testPHP8MixedTypeHintNullable */',
[
'scope' => 'private',
'scope_specified' => true,
'is_static' => false,
'type' => '?mixed',
'nullable_type' => true,
],
],
[
'/* testPHP8UnionTypesSimple */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'type' => 'int|float',
'nullable_type' => false,
],
],
[
'/* testPHP8UnionTypesTwoClasses */',
[
'scope' => 'private',
'scope_specified' => true,
'is_static' => false,
'type' => 'MyClassA|\Package\MyClassB',
'nullable_type' => false,
],
],
[
'/* testPHP8UnionTypesAllBaseTypes */',
[
'scope' => 'protected',
'scope_specified' => true,
'is_static' => false,
'type' => 'array|bool|int|float|NULL|object|string',
'nullable_type' => false,
],
],
[
'/* testPHP8UnionTypesAllPseudoTypes */',
[
'scope' => 'public',
'scope_specified' => false,
'is_static' => false,
// Note: "Resource" is not a type, but seen as a class name.
'type' => 'false|mixed|self|parent|iterable|Resource',
'nullable_type' => false,
],
],
[
'/* testPHP8UnionTypesIllegalTypes */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
// Missing static, but that's OK as it's not an allowed syntax.
'type' => 'callable||void',
'nullable_type' => false,
],
],
[
'/* testPHP8UnionTypesNullable */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'type' => '?int|float',
'nullable_type' => true,
],
],
[
'/* testPHP8PseudoTypeNull */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'type' => 'null',
'nullable_type' => false,
],
],
[
'/* testPHP8PseudoTypeFalse */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'type' => 'false',
'nullable_type' => false,
],
],
[
'/* testPHP8PseudoTypeFalseAndBool */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'type' => 'bool|FALSE',
'nullable_type' => false,
],
],
[
'/* testPHP8ObjectAndClass */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'type' => 'object|ClassName',
'nullable_type' => false,
],
],
[
'/* testPHP8PseudoTypeIterableAndArray */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'type' => 'iterable|array|Traversable',
'nullable_type' => false,
],
],
[
'/* testPHP8DuplicateTypeInUnion */',
[
'scope' => 'public',
'scope_specified' => true,
'is_static' => false,
'type' => 'int|string|INT',
'nullable_type' => false,
],
],
];

}//end dataGetMemberProperties()
Expand Down