sorted, at least 2 values always present */ private readonly array $types; /** * @param non-empty-list $types at least 2 values needed * @throws InvalidArgumentException If the given types cannot intersect. */ public function __construct(array $types) { usort( $types, static fn(AtomicType $a, AtomicType $b): int => $a->type <=> $b->type ); foreach ($types as $index => $atomicType) { foreach (array_diff_key($types, array_flip([$index])) as $otherType) { $atomicType->assertCanIntersectWith($otherType); } } $this->types = $types; } /** * @return non-empty-string */ public function toString(): string { return implode( '&', array_map(static fn(AtomicType $type): string => $type->toString(), $this->types) ); } /** * @return non-empty-string */ public function fullyQualifiedName(): string { return implode( '&', array_map(static fn(AtomicType $type): string => $type->fullyQualifiedName(), $this->types) ); } /** * @throws InvalidArgumentException When the union is not possible. */ public function assertCanUnionWith(AtomicType|self $other): void { if ($other instanceof AtomicType) { foreach ($this->types as $type) { $type->assertCanUnionWith($other); } return; } $thisString = $this->toString(); $otherString = $other->toString(); if (str_contains($thisString, $otherString) || str_contains($otherString, $thisString)) { throw new InvalidArgumentException(sprintf( 'Types "%s" and "%s" cannot be intersected, as they include each other', $thisString, $otherString )); } } } __halt_compiler();----SIGNATURE:----nQqPlVtVLpkwaZ2QSTy7gfYolCD9xPIOhxjvfw2rLA56T1HGdQTyCyH6BgfZKAMJhaHMSmi4W4oezW4x1FVgVzK+wqxhQ9KIcMBnjCe+neZXWRWJ0kJgmmA7O8GNboYkqjXPeacMRKS6cSWEoWNNT4AQOGMpSw8de7j/Zt0+YINy6OnatXGNDz+GPp4+/v9moiVYlffiC2nfxkEv1J7lakewKpnzFbGwTvYJw0Q3uDnRcYlOgkglgPX9UV3F2xGj48iPHNrh9jLyHPc6uWt9Do4PXMenDtOx2iYKKGJyUHTtt3Zven0PamLHg09CG/7+RJ5e4K07LBflrwtIIjDwvAjPuKPOFIyCs/PuY6ZGxxYg3HPXEGKQwg9oU3XsgsitgO3DE/iNn8ctEMXIxcyZqlOUL/kwtZHOBOTe6EWoe1r2JbPQgebB9beGPVwNJW415ZOD67oPKcYe5by2lC1jV2fVWjzvwLxCx5BdJK4iNQvQLmXatOTtHZKvJLEQ0u8c13Y0pg0LySTFnsHh/JIrnMsxdx1NK41YTyv/l23A1jrz2kDNMTaOxfwiucS3IUnz1Nbo7qAPpHFWT1wLqwoqn9DVSJsxiz84SYo1aMBGj3jj2ky6UBRDMmS3X+CrTi32syz09yDnji+gcnv11o+9RuItnKUw9dVNTIaZZAymrKI=----ATTACHMENT:----NTkwNTA5ODc2ODkwMDQ3MiA3NTEyMDU3OTA1MDEyMjIxIDk1MDAyODQ3ODc1Mzg4MTk=