@@ -548,31 +548,26 @@ public function equals(SimpleType $other): bool {
548
548
class Type {
549
549
/** @var SimpleType[] */
550
550
public $ types ;
551
+ /** @var bool */
552
+ public $ isIntersection = false ;
551
553
552
554
public static function fromNode (Node $ node ): Type {
553
- if ($ node instanceof Node \UnionType) {
555
+ if ($ node instanceof Node \UnionType || $ node instanceof Node \IntersectionType ) {
554
556
$ nestedTypeObjects = array_map (['Type ' , 'fromNode ' ], $ node ->types );
555
557
$ types = [];
556
558
foreach ($ nestedTypeObjects as $ typeObject ) {
557
559
array_push ($ types , ...$ typeObject ->types );
558
560
}
559
- return new Type ($ types );
560
- }
561
- if ($ node instanceof Node \IntersectionType) {
562
- $ nestedTypeObjects = array_map (['Type ' , 'fromNode ' ], $ node ->types );
563
- $ types = [];
564
- foreach ($ nestedTypeObjects as $ typeObject ) {
565
- array_push ($ types , ...$ typeObject ->types );
566
- }
567
- return new Type ($ types , true );
561
+ return new Type ($ types , ($ node instanceof Node \IntersectionType));
568
562
}
569
563
570
564
if ($ node instanceof Node \NullableType) {
571
565
return new Type (
572
566
[
573
567
...Type::fromNode ($ node ->type )->types ,
574
568
SimpleType::null (),
575
- ]
569
+ ],
570
+ false
576
571
);
577
572
}
578
573
@@ -581,18 +576,20 @@ public static function fromNode(Node $node): Type {
581
576
[
582
577
SimpleType::fromString ("Traversable " ),
583
578
ArrayType::createGenericArray (),
584
- ]
579
+ ],
580
+ false
585
581
);
586
582
}
587
583
588
- return new Type ([SimpleType::fromNode ($ node )]);
584
+ return new Type ([SimpleType::fromNode ($ node )], false );
589
585
}
590
586
591
587
public static function fromString (string $ typeString ): self {
592
588
$ typeString .= "| " ;
593
589
$ simpleTypes = [];
594
590
$ simpleTypeOffset = 0 ;
595
591
$ inArray = false ;
592
+ $ isIntersection = false ;
596
593
597
594
$ typeStringLength = strlen ($ typeString );
598
595
for ($ i = 0 ; $ i < $ typeStringLength ; $ i ++) {
@@ -612,7 +609,8 @@ public static function fromString(string $typeString): self {
612
609
continue ;
613
610
}
614
611
615
- if ($ char === "| " ) {
612
+ if ($ char === "| " || $ char === "& " ) {
613
+ $ isIntersection = ($ char === "& " );
616
614
$ simpleTypeName = trim (substr ($ typeString , $ simpleTypeOffset , $ i - $ simpleTypeOffset ));
617
615
618
616
$ simpleTypes [] = SimpleType::fromString ($ simpleTypeName );
@@ -621,14 +619,15 @@ public static function fromString(string $typeString): self {
621
619
}
622
620
}
623
621
624
- return new Type ($ simpleTypes );
622
+ return new Type ($ simpleTypes, $ isIntersection );
625
623
}
626
624
627
625
/**
628
626
* @param SimpleType[] $types
629
627
*/
630
- private function __construct (array $ types , public readonly bool $ isIntersection = false ) {
628
+ private function __construct (array $ types , bool $ isIntersection ) {
631
629
$ this ->types = $ types ;
630
+ $ this ->isIntersection = $ isIntersection ;
632
631
}
633
632
634
633
public function isScalar (): bool {
@@ -658,7 +657,8 @@ public function getWithoutNull(): Type {
658
657
function (SimpleType $ type ) {
659
658
return !$ type ->isNull ();
660
659
}
661
- )
660
+ ),
661
+ false
662
662
);
663
663
}
664
664
@@ -691,6 +691,7 @@ public function toOptimizerTypeMask(): string {
691
691
$ optimizerTypes = [];
692
692
693
693
foreach ($ this ->types as $ type ) {
694
+ // TODO Support for toOptimizerMask for intersection
694
695
$ optimizerTypes [] = $ type ->toOptimizerTypeMask ();
695
696
}
696
697
@@ -719,8 +720,9 @@ public function toOptimizerTypeMaskForArrayValue(): string {
719
720
720
721
public function getTypeForDoc (DOMDocument $ doc ): DOMElement {
721
722
if (count ($ this ->types ) > 1 ) {
723
+ $ typeSort = $ this ->isIntersection ? "intersection " : "union " ;
722
724
$ typeElement = $ doc ->createElement ('type ' );
723
- $ typeElement ->setAttribute ("class " , " union " );
725
+ $ typeElement ->setAttribute ("class " , $ typeSort );
724
726
725
727
foreach ($ this ->types as $ type ) {
726
728
$ unionTypeElement = $ doc ->createElement ('type ' , $ type ->name );
@@ -763,7 +765,8 @@ public function __toString() {
763
765
return 'mixed ' ;
764
766
}
765
767
766
- return implode ('| ' , array_map (
768
+ $ char = $ this ->isIntersection ? '& ' : '| ' ;
769
+ return implode ($ char , array_map (
767
770
function ($ type ) { return $ type ->name ; },
768
771
$ this ->types )
769
772
);
0 commit comments