assertCanBeStandaloneNullable(); } } /** * @internal * * @psalm-pure */ public static function fromReflectionType( ReflectionNamedType|ReflectionUnionType|ReflectionIntersectionType|null $type, ?ReflectionClass $currentClass, ): ?self { if (null === $type) { return null; } if ($type instanceof ReflectionUnionType) { return new self( new UnionType(array_map( static fn( ReflectionIntersectionType|ReflectionNamedType $type ): IntersectionType|AtomicType => $type instanceof ReflectionNamedType ? AtomicType::fromReflectionNamedTypeAndClass($type, $currentClass) : self::fromIntersectionType($type, $currentClass), $type->getTypes() )), false ); } if ($type instanceof ReflectionIntersectionType) { return new self(self::fromIntersectionType($type, $currentClass), false); } $atomicType = AtomicType::fromReflectionNamedTypeAndClass($type, $currentClass); return new self( $atomicType, $atomicType->type !== 'mixed' && $atomicType !== 'null' && $type->allowsNull() ); } /** * @psalm-pure */ private static function fromIntersectionType( ReflectionIntersectionType $intersectionType, ?ReflectionClass $currentClass, ): IntersectionType { return new IntersectionType(array_map( static fn( ReflectionNamedType $type ): AtomicType => AtomicType::fromReflectionNamedTypeAndClass($type, $currentClass), $intersectionType->getTypes() )); } /** * @throws InvalidArgumentException * @psalm-pure */ public static function fromTypeString(string $type): self { [$nullable, $trimmedNullable] = self::trimNullable($type); if ( ! str_contains($trimmedNullable, CompositeType::INTERSECTION_SEPARATOR) && ! str_contains($trimmedNullable, CompositeType::UNION_SEPARATOR) ) { return new self(CompositeType::fromString($trimmedNullable), $nullable); } if ($nullable) { throw new InvalidArgumentException(sprintf( 'Type "%s" is a union type, and therefore cannot be also marked nullable with the "?" prefix', $type )); } return new self(CompositeType::fromString($trimmedNullable)); } /** * {@inheritDoc} * * Generates the type string, including FQCN "\\" prefix, so that * it can directly be used within any code snippet, regardless of * imports. * * @psalm-return non-empty-string */ public function generate(): string { return ($this->nullable ? self::NULL_MARKER : '') . $this->type->fullyQualifiedName(); } public function equals(TypeGenerator $otherType): bool { return $this->generate() === $otherType->generate(); } /** * @return non-empty-string the cleaned type string. Note that this value is not suitable for code generation, * since the returned value does not include any root namespace prefixes, when applicable, * and therefore the values cannot be used as FQCN in generated code. */ public function __toString(): string { return $this->type->toString(); } /** * @return bool[]|string[] ordered tuple, first key represents whether the type is nullable, second is the * trimmed string * @psalm-return array{bool, string} * @psalm-pure */ private static function trimNullable(string $type): array { if (str_starts_with($type, self::NULL_MARKER)) { return [true, substr($type, 1)]; } return [false, $type]; } } __halt_compiler();----SIGNATURE:----Mdy+xRNLBcE5mhWG7dMt/zQr28pJ86hlLg8uCBq+9uYNI0d0mHSib9+bAepAu0dZU7yYoufBjZHGvLNMzJFp4GjR2P7ROWekUJlVIosQcLABEY9sEDLcAdElnHVnoSt7PXKV6m9K93OvqNqax6WlDmZQfFntVoWF5MFlZCqa1acLy5HkJcXObuWbyMyWeAyoqI2bG0+NLP9Gm9giiYIk0PWybHoBtrd5a1YcWOZwQUg5QLCIwe1+xPiJilE50wSjxCrCiPDzYMzSIjauxp2qI2hkmKGoPQQ2oPw5kxIrrBw/gPLFT5qqI/u8rXGrzGJ/mZf0YWQtwaYwN1tY+M7BFkxzp21IPeRGs7FKRgl/XDVNPc8Pl0nwfcrmzYie2LzY+O3BXIkSTfuaYDZlnLQAv+lRFX9iq9PZoYVhYgRZxeS5TVHFfnkEoXwccABK7ecvtwUUwIuGbYyQUMZmZcWcZ+bBzBq9E8ei8ceuGG4Bqq4XrjdvN6zZlnxItsa++jlbpmAMmP0q2w1GChsa7mDV4MizDyo3ymaBjNb9g8db4sN/VGwVXMQgybcrHUAizbzWL91Z+UQ+kFCl/B7qb+/1M6cyx3nQ+cxRxEYLbPnGaScp4Tovkr7B3Zap6Y9Aw4JqZw8fRUbAljua30mvepzxdtAUz1z1npVaPMm33shMee4=----ATTACHMENT:----MzIwMDE1NDYxODgyOTk5NiA4NTUyMTI0NDg4NDA4OTMyIDQ4NjA5MDc0MTg5Mzg4MDE=