@@ -503,31 +503,26 @@ public function equals(SimpleType $other): bool {
503
503
class Type {
504
504
/** @var SimpleType[] */
505
505
public $ types ;
506
+ /** @var bool */
507
+ public $ isIntersection = false ;
506
508
507
509
public static function fromNode (Node $ node ): Type {
508
- if ($ node instanceof Node \UnionType) {
510
+ if ($ node instanceof Node \UnionType || $ node instanceof Node \IntersectionType ) {
509
511
$ nestedTypeObjects = array_map (['Type ' , 'fromNode ' ], $ node ->types );
510
512
$ types = [];
511
513
foreach ($ nestedTypeObjects as $ typeObject ) {
512
514
array_push ($ types , ...$ typeObject ->types );
513
515
}
514
- return new Type ($ types );
515
- }
516
- if ($ node instanceof Node \IntersectionType) {
517
- $ nestedTypeObjects = array_map (['Type ' , 'fromNode ' ], $ node ->types );
518
- $ types = [];
519
- foreach ($ nestedTypeObjects as $ typeObject ) {
520
- array_push ($ types , ...$ typeObject ->types );
521
- }
522
- return new Type ($ types , true );
516
+ return new Type ($ types , ($ node instanceof Node \IntersectionType));
523
517
}
524
518
525
519
if ($ node instanceof Node \NullableType) {
526
520
return new Type (
527
521
[
528
522
...Type::fromNode ($ node ->type )->types ,
529
523
SimpleType::null (),
530
- ]
524
+ ],
525
+ false
531
526
);
532
527
}
533
528
@@ -536,18 +531,20 @@ public static function fromNode(Node $node): Type {
536
531
[
537
532
SimpleType::fromString ("Traversable " ),
538
533
ArrayType::createGenericArray (),
539
- ]
534
+ ],
535
+ false
540
536
);
541
537
}
542
538
543
- return new Type ([SimpleType::fromNode ($ node )]);
539
+ return new Type ([SimpleType::fromNode ($ node )], false );
544
540
}
545
541
546
542
public static function fromString (string $ typeString ): self {
547
543
$ typeString .= "| " ;
548
544
$ simpleTypes = [];
549
545
$ simpleTypeOffset = 0 ;
550
546
$ inArray = false ;
547
+ $ isIntersection = false ;
551
548
552
549
$ typeStringLength = strlen ($ typeString );
553
550
for ($ i = 0 ; $ i < $ typeStringLength ; $ i ++) {
@@ -567,7 +564,8 @@ public static function fromString(string $typeString): self {
567
564
continue ;
568
565
}
569
566
570
- if ($ char === "| " ) {
567
+ if ($ char === "| " || $ char === "& " ) {
568
+ $ isIntersection = ($ char === "& " );
571
569
$ simpleTypeName = trim (substr ($ typeString , $ simpleTypeOffset , $ i - $ simpleTypeOffset ));
572
570
573
571
$ simpleTypes [] = SimpleType::fromString ($ simpleTypeName );
@@ -576,14 +574,15 @@ public static function fromString(string $typeString): self {
576
574
}
577
575
}
578
576
579
- return new Type ($ simpleTypes );
577
+ return new Type ($ simpleTypes, $ isIntersection );
580
578
}
581
579
582
580
/**
583
581
* @param SimpleType[] $types
584
582
*/
585
- private function __construct (array $ types , public readonly bool $ isIntersection = false ) {
583
+ private function __construct (array $ types , bool $ isIntersection ) {
586
584
$ this ->types = $ types ;
585
+ $ this ->isIntersection = $ isIntersection ;
587
586
}
588
587
589
588
public function isScalar (): bool {
@@ -613,7 +612,8 @@ public function getWithoutNull(): Type {
613
612
function (SimpleType $ type ) {
614
613
return !$ type ->isNull ();
615
614
}
616
- )
615
+ ),
616
+ false
617
617
);
618
618
}
619
619
@@ -646,6 +646,7 @@ public function toOptimizerTypeMask(): string {
646
646
$ optimizerTypes = [];
647
647
648
648
foreach ($ this ->types as $ type ) {
649
+ // TODO Support for toOptimizerMask for intersection
649
650
$ optimizerTypes [] = $ type ->toOptimizerTypeMask ();
650
651
}
651
652
@@ -674,8 +675,9 @@ public function toOptimizerTypeMaskForArrayValue(): string {
674
675
675
676
public function getTypeForDoc (DOMDocument $ doc ): DOMElement {
676
677
if (count ($ this ->types ) > 1 ) {
678
+ $ typeSort = $ this ->isIntersection ? "intersection " : "union " ;
677
679
$ typeElement = $ doc ->createElement ('type ' );
678
- $ typeElement ->setAttribute ("class " , " union " );
680
+ $ typeElement ->setAttribute ("class " , $ typeSort );
679
681
680
682
foreach ($ this ->types as $ type ) {
681
683
$ unionTypeElement = $ doc ->createElement ('type ' , $ type ->name );
@@ -718,7 +720,8 @@ public function __toString() {
718
720
return 'mixed ' ;
719
721
}
720
722
721
- return implode ('| ' , array_map (
723
+ $ char = $ this ->isIntersection ? '& ' : '| ' ;
724
+ return implode ($ char , array_map (
722
725
function ($ type ) { return $ type ->name ; },
723
726
$ this ->types )
724
727
);
0 commit comments