Skip to content

Commit b552768

Browse files
committed
PHP 8.0 | File::getMemberProperties(): add support for "union" types
This adds support for union types to the `File::getMemberProperties()` method. Includes extensive unit tests.
1 parent 38c01b3 commit b552768

File tree

3 files changed

+171
-0
lines changed

3 files changed

+171
-0
lines changed

src/Files/File.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1821,8 +1821,11 @@ public function getMemberProperties($stackPtr)
18211821
T_CALLABLE => T_CALLABLE,
18221822
T_SELF => T_SELF,
18231823
T_PARENT => T_PARENT,
1824+
T_FALSE => T_FALSE,
1825+
T_NULL => T_NULL,
18241826
T_NAMESPACE => T_NAMESPACE,
18251827
T_NS_SEPARATOR => T_NS_SEPARATOR,
1828+
T_TYPE_UNION => T_TYPE_UNION,
18261829
];
18271830

18281831
for ($i; $i < $stackPtr; $i++) {

tests/Core/File/GetMemberPropertiesTest.inc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,50 @@ class NSOperatorInType {
193193
/* testNamespaceOperatorTypeHint */
194194
public ?namespace\Name $prop;
195195
}
196+
197+
$anon = class() {
198+
/* testPHP8UnionTypesSimple */
199+
public int|float $unionTypeSimple;
200+
201+
/* testPHP8UnionTypesTwoClasses */
202+
private MyClassA|\Package\MyClassB $unionTypesTwoClasses;
203+
204+
/* testPHP8UnionTypesAllBaseTypes */
205+
protected array|bool|int|float|NULL|object|string $unionTypesAllBaseTypes;
206+
207+
/* testPHP8UnionTypesAllPseudoTypes */
208+
// Intentional fatal error - mixing types which cannot be combined, but that's not the concern of the method.
209+
var false|mixed|self|parent|iterable|Resource $unionTypesAllPseudoTypes;
210+
211+
/* testPHP8UnionTypesIllegalTypes */
212+
// Intentional fatal error - types which are not allowed for properties, but that's not the concern of the method.
213+
public callable|static|void $unionTypesIllegalTypes;
214+
215+
/* testPHP8UnionTypesNullable */
216+
// Intentional fatal error - nullability is not allowed with union types, but that's not the concern of the method.
217+
public ?int|float $unionTypesNullable;
218+
219+
/* testPHP8PseudoTypeNull */
220+
// Intentional fatal error - null pseudotype is only allowed in union types, but that's not the concern of the method.
221+
public null $pseudoTypeNull;
222+
223+
/* testPHP8PseudoTypeFalse */
224+
// Intentional fatal error - false pseudotype is only allowed in union types, but that's not the concern of the method.
225+
public false $pseudoTypeFalse;
226+
227+
/* testPHP8PseudoTypeFalseAndBool */
228+
// Intentional fatal error - false pseudotype is not allowed in combination with bool, but that's not the concern of the method.
229+
public bool|FALSE $pseudoTypeFalseAndBool;
230+
231+
/* testPHP8ObjectAndClass */
232+
// Intentional fatal error - object is not allowed in combination with class name, but that's not the concern of the method.
233+
public object|ClassName $objectAndClass;
234+
235+
/* testPHP8PseudoTypeIterableAndArray */
236+
// Intentional fatal error - iterable pseudotype is not allowed in combination with array or Traversable, but that's not the concern of the method.
237+
public iterable|array|Traversable $pseudoTypeIterableAndArray;
238+
239+
/* testPHP8DuplicateTypeInUnionWhitespaceAndComment */
240+
// Intentional fatal error - duplicate types are not allowed in union types, but that's not the concern of the method.
241+
public int |string| /*comment*/ INT $duplicateTypeInUnion;
242+
};

tests/Core/File/GetMemberPropertiesTest.php

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,127 @@ public function dataGetMemberProperties()
489489
'nullable_type' => true,
490490
],
491491
],
492+
[
493+
'/* testPHP8UnionTypesSimple */',
494+
[
495+
'scope' => 'public',
496+
'scope_specified' => true,
497+
'is_static' => false,
498+
'type' => 'int|float',
499+
'nullable_type' => false,
500+
],
501+
],
502+
[
503+
'/* testPHP8UnionTypesTwoClasses */',
504+
[
505+
'scope' => 'private',
506+
'scope_specified' => true,
507+
'is_static' => false,
508+
'type' => 'MyClassA|\Package\MyClassB',
509+
'nullable_type' => false,
510+
],
511+
],
512+
[
513+
'/* testPHP8UnionTypesAllBaseTypes */',
514+
[
515+
'scope' => 'protected',
516+
'scope_specified' => true,
517+
'is_static' => false,
518+
'type' => 'array|bool|int|float|NULL|object|string',
519+
'nullable_type' => false,
520+
],
521+
],
522+
[
523+
'/* testPHP8UnionTypesAllPseudoTypes */',
524+
[
525+
'scope' => 'public',
526+
'scope_specified' => false,
527+
'is_static' => false,
528+
'type' => 'false|mixed|self|parent|iterable|Resource',
529+
'nullable_type' => false,
530+
],
531+
],
532+
[
533+
'/* testPHP8UnionTypesIllegalTypes */',
534+
[
535+
'scope' => 'public',
536+
'scope_specified' => true,
537+
'is_static' => false,
538+
// Missing static, but that's OK as not an allowed syntax.
539+
'type' => 'callable||void',
540+
'nullable_type' => false,
541+
],
542+
],
543+
[
544+
'/* testPHP8UnionTypesNullable */',
545+
[
546+
'scope' => 'public',
547+
'scope_specified' => true,
548+
'is_static' => false,
549+
'type' => '?int|float',
550+
'nullable_type' => true,
551+
],
552+
],
553+
[
554+
'/* testPHP8PseudoTypeNull */',
555+
[
556+
'scope' => 'public',
557+
'scope_specified' => true,
558+
'is_static' => false,
559+
'type' => 'null',
560+
'nullable_type' => false,
561+
],
562+
],
563+
[
564+
'/* testPHP8PseudoTypeFalse */',
565+
[
566+
'scope' => 'public',
567+
'scope_specified' => true,
568+
'is_static' => false,
569+
'type' => 'false',
570+
'nullable_type' => false,
571+
],
572+
],
573+
[
574+
'/* testPHP8PseudoTypeFalseAndBool */',
575+
[
576+
'scope' => 'public',
577+
'scope_specified' => true,
578+
'is_static' => false,
579+
'type' => 'bool|FALSE',
580+
'nullable_type' => false,
581+
],
582+
],
583+
[
584+
'/* testPHP8ObjectAndClass */',
585+
[
586+
'scope' => 'public',
587+
'scope_specified' => true,
588+
'is_static' => false,
589+
'type' => 'object|ClassName',
590+
'nullable_type' => false,
591+
],
592+
],
593+
[
594+
'/* testPHP8PseudoTypeIterableAndArray */',
595+
[
596+
'scope' => 'public',
597+
'scope_specified' => true,
598+
'is_static' => false,
599+
'type' => 'iterable|array|Traversable',
600+
'nullable_type' => false,
601+
],
602+
],
603+
[
604+
'/* testPHP8DuplicateTypeInUnionWhitespaceAndComment */',
605+
[
606+
'scope' => 'public',
607+
'scope_specified' => true,
608+
'is_static' => false,
609+
'type' => 'int|string|INT',
610+
'nullable_type' => false,
611+
],
612+
],
492613
];
493614

494615
}//end dataGetMemberProperties()

0 commit comments

Comments
 (0)