Skip to content

[TypeInfo] fails to parse scalar definition #60620

@norkunas

Description

@norkunas

Symfony version(s) affected

7.3

Description

We have a property with this type definition:

    /**
     * @var list<array{value: scalar|null, header: string}>
     */
    #[Column(type: Types::JSON)]
    private array $exifData;

And now tried to bump dependencies to Symfony 7.3 and it explodes:

Symfony\Component\TypeInfo\Exception\InvalidArgumentException:
Cannot set "Symfony\Component\TypeInfo\Type\UnionType" as a "Symfony\Component\TypeInfo\Type\UnionType" part.

  at /var/www/html/vendor/symfony/type-info/Type/UnionType.php:44
  at Symfony\Component\TypeInfo\Type\UnionType->__construct(object(BuiltinType), object(UnionType))
     (/var/www/html/vendor/symfony/type-info/TypeFactoryTrait.php:334)
  at Symfony\Component\TypeInfo\Type::union(object(BuiltinType), object(NullableType))
     (/var/www/html/vendor/symfony/type-info/Type/CollectionType.php:105)
  at Symfony\Component\TypeInfo\Type\CollectionType::mergeCollectionValueTypes(array(object(NullableType), object(BuiltinType)))
     (/var/www/html/vendor/symfony/type-info/Type/ArrayShapeType.php:55)
  at Symfony\Component\TypeInfo\Type\ArrayShapeType->__construct(array('value' => array('type' => object(NullableType), 'optional' => false), 'header' => array('type' => object(BuiltinType), 'optional' => false)), null, null)
     (/var/www/html/vendor/symfony/type-info/TypeFactoryTrait.php:216)
  at Symfony\Component\TypeInfo\Type::arrayShape(array('value' => array('type' => object(NullableType), 'optional' => false), 'header' => array('type' => object(BuiltinType), 'optional' => false)), true, null, null)
     (/var/www/html/vendor/symfony/type-info/TypeResolver/StringTypeResolver.php:113)
  at Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver->getTypeFromNode(object(ArrayShapeNode), object(TypeContext))
     (/var/www/html/vendor/symfony/type-info/TypeResolver/StringTypeResolver.php:205)
  at Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver->Symfony\Component\TypeInfo\TypeResolver\{closure}(object(ArrayShapeNode))
  at array_map(object(Closure), array(object(ArrayShapeNode)))
     (/var/www/html/vendor/symfony/type-info/TypeResolver/StringTypeResolver.php:205)
  at Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver->getTypeFromNode(object(GenericTypeNode), object(TypeContext))
     (/var/www/html/vendor/symfony/type-info/TypeResolver/StringTypeResolver.php:86)
  at Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver->resolve('list<array{value: (scalar | null), header: string}>', object(TypeContext))
     (/var/www/html/vendor/symfony/property-info/Extractor/PhpStanExtractor.php:230)
  at Symfony\Component\PropertyInfo\Extractor\PhpStanExtractor->getType('App\\Media\\Entity\\MediaObject', 'exifData', array())
     (/var/www/html/vendor/symfony/property-info/PropertyInfoExtractor.php:70)
  at Symfony\Component\PropertyInfo\PropertyInfoExtractor->getType('App\\Media\\Entity\\MediaObject', 'exifData')
     (/var/www/html/vendor/symfony/validator/Mapping/Loader/PropertyInfoLoader.php:193)
  at Symfony\Component\Validator\Mapping\Loader\PropertyInfoLoader->getPropertyTypes('App\\Media\\Entity\\MediaObject', 'exifData')
     (/var/www/html/vendor/symfony/validator/Mapping/Loader/PropertyInfoLoader.php:70)
  at Symfony\Component\Validator\Mapping\Loader\PropertyInfoLoader->loadClassMetadata(object(ClassMetadata))
     (/var/www/html/vendor/symfony/validator/Mapping/Loader/LoaderChain.php:48)
  at Symfony\Component\Validator\Mapping\Loader\LoaderChain->loadClassMetadata(object(ClassMetadata))
     (/var/www/html/vendor/symfony/validator/Mapping/Factory/LazyLoadingMetadataFactory.php:96)
  at Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory->getMetadataFor('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/symfony/validator/Validator/RecursiveValidator.php:70)
  at Symfony\Component\Validator\Validator\RecursiveValidator->getMetadataFor('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/symfony/validator/Validator/TraceableValidator.php:48)
  at Symfony\Component\Validator\Validator\TraceableValidator->getMetadataFor('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/symfony/Validator/Metadata/Property/ValidatorPropertyMetadataFactory.php:101)
  at ApiPlatform\Symfony\Validator\Metadata\Property\ValidatorPropertyMetadataFactory->create('App\\Media\\Entity\\MediaObject', 'id', array())
     (/var/www/html/vendor/api-platform/json-schema/Metadata/Property/Factory/SchemaPropertyMetadataFactory.php:50)
  at ApiPlatform\JsonSchema\Metadata\Property\Factory\SchemaPropertyMetadataFactory->create('App\\Media\\Entity\\MediaObject', 'id', array())
     (/var/www/html/vendor/api-platform/metadata/Property/Factory/CachedPropertyMetadataFactory.php:43)
  at ApiPlatform\Metadata\Property\Factory\CachedPropertyMetadataFactory->ApiPlatform\Metadata\Property\Factory\{closure}()
     (/var/www/html/vendor/api-platform/metadata/Util/CachedTrait.php:43)
  at ApiPlatform\Metadata\Property\Factory\CachedPropertyMetadataFactory->getCached('property_metadata_5dab76212df1d3a2', object(Closure))
     (/var/www/html/vendor/api-platform/metadata/Property/Factory/CachedPropertyMetadataFactory.php:43)
  at ApiPlatform\Metadata\Property\Factory\CachedPropertyMetadataFactory->create('App\\Media\\Entity\\MediaObject', 'id')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/LinkFactory.php:160)
  at ApiPlatform\Metadata\Resource\Factory\LinkFactory->getIdentifiersFromResourceClass('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/LinkFactory.php:59)
  at ApiPlatform\Metadata\Resource\Factory\LinkFactory->createLinksFromIdentifiers(object(ApiResource))
     (/var/www/html/vendor/api-platform/doctrine-orm/Metadata/Resource/DoctrineOrmLinkFactory.php:47)
  at ApiPlatform\Doctrine\Orm\Metadata\Resource\DoctrineOrmLinkFactory->createLinksFromIdentifiers(object(ApiResource))
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/UriTemplateResourceMetadataCollectionFactory.php:137)
  at ApiPlatform\Metadata\Resource\Factory\UriTemplateResourceMetadataCollectionFactory->configureUriVariables(object(ApiResource))
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/UriTemplateResourceMetadataCollectionFactory.php:48)
  at ApiPlatform\Metadata\Resource\Factory\UriTemplateResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/MainControllerResourceMetadataCollectionFactory.php:38)
  at ApiPlatform\Metadata\Resource\Factory\MainControllerResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/LinkResourceMetadataCollectionFactory.php:37)
  at ApiPlatform\Metadata\Resource\Factory\LinkResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/OperationNameResourceMetadataCollectionFactory.php:39)
  at ApiPlatform\Metadata\Resource\Factory\OperationNameResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/InputOutputResourceMetadataCollectionFactory.php:37)
  at ApiPlatform\Metadata\Resource\Factory\InputOutputResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/FormatsResourceMetadataCollectionFactory.php:53)
  at ApiPlatform\Metadata\Resource\Factory\FormatsResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/FiltersResourceMetadataCollectionFactory.php:41)
  at ApiPlatform\Metadata\Resource\Factory\FiltersResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/AlternateUriResourceMetadataCollectionFactory.php:34)
  at ApiPlatform\Metadata\Resource\Factory\AlternateUriResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/PhpDocResourceMetadataCollectionFactory.php:79)
  at ApiPlatform\Metadata\Resource\Factory\PhpDocResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/symfony/Messenger/Metadata/MessengerResourceMetadataCollectionFactory.php:31)
  at ApiPlatform\Symfony\Messenger\Metadata\MessengerResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/doctrine-orm/Metadata/Resource/DoctrineOrmResourceCollectionMetadataFactory.php:42)
  at ApiPlatform\Doctrine\Orm\Metadata\Resource\DoctrineOrmResourceCollectionMetadataFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/metadata/Resource/Factory/CachedResourceMetadataCollectionFactory.php:59)
  at ApiPlatform\Metadata\Resource\Factory\CachedResourceMetadataCollectionFactory->create('App\\Media\\Entity\\MediaObject')
     (/var/www/html/vendor/api-platform/symfony/Routing/ApiLoader.php:58)
  at ApiPlatform\Symfony\Routing\ApiLoader->load('.', 'api_platform')
     (/var/www/html/vendor/symfony/config/Loader/FileLoader.php:141)
  at Symfony\Component\Config\Loader\FileLoader->doImport('.', 'api_platform', false, '/var/www/html/config/routes/api_platform.php')
     (/var/www/html/vendor/symfony/config/Loader/FileLoader.php:93)
  at Symfony\Component\Config\Loader\FileLoader->import('.', 'api_platform', false, '/var/www/html/config/routes/api_platform.php', null)
     (/var/www/html/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php:41)
  at Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator->import('.', 'api_platform')
     (/var/www/html/config/routes/api_platform.php:9)
  at Symfony\Component\Routing\Loader\ProtectedPhpFileLoader::{closure}(object(RoutingConfigurator))
     (/var/www/html/vendor/symfony/routing/Loader/PhpFileLoader.php:66)
  at Symfony\Component\Routing\Loader\PhpFileLoader->callConfigurator(object(Closure), '/var/www/html/config/routes/api_platform.php', '/var/www/html/config/routes/api_platform.php')
     (/var/www/html/vendor/symfony/routing/Loader/PhpFileLoader.php:47)
  at Symfony\Component\Routing\Loader\PhpFileLoader->load('/var/www/html/config/routes/api_platform.php', null)
     (/var/www/html/vendor/symfony/config/Loader/FileLoader.php:162)
  at Symfony\Component\Config\Loader\FileLoader->doImport('/var/www/html/config/routes/api_platform.php', null, false, '/var/www/html/src/Kernel.php')
     (/var/www/html/vendor/symfony/config/Loader/FileLoader.php:82)
  at Symfony\Component\Config\Loader\FileLoader->import('/var/www/html/{config}/{routes}/*.{php,yaml}', null, false, '/var/www/html/src/Kernel.php', null)
     (/var/www/html/vendor/symfony/routing/Loader/Configurator/RoutingConfigurator.php:41)
  at Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator->import('/var/www/html/{config}/{routes}/*.{php,yaml}')
     (/var/www/html/vendor/symfony/framework-bundle/Kernel/MicroKernelTrait.php:80)
  at App\Kernel->configureRoutes(object(RoutingConfigurator))
     (/var/www/html/vendor/symfony/framework-bundle/Kernel/MicroKernelTrait.php:217)
  at App\Kernel->loadRoutes(object(ContainerLoader), 'dev')
     (/var/www/html/vendor/symfony/routing/Loader/ObjectLoader.php:51)
  at Symfony\Component\Routing\Loader\ObjectLoader->load('kernel::loadRoutes', 'service')
     (/var/www/html/vendor/symfony/config/Loader/DelegatingLoader.php:37)
  at Symfony\Component\Config\Loader\DelegatingLoader->load('kernel::loadRoutes', 'service')
     (/var/www/html/vendor/symfony/framework-bundle/Routing/DelegatingLoader.php:65)
  at Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader->load('kernel::loadRoutes', 'service')
     (/var/www/html/vendor/symfony/framework-bundle/Routing/Router.php:72)
  at Symfony\Bundle\FrameworkBundle\Routing\Router->getRouteCollection()
     (/var/www/html/vendor/symfony/routing/Router.php:282)
  at Symfony\Component\Routing\Router->getMatcherDumperInstance()
     (/var/www/html/vendor/symfony/routing/Router.php:218)
  at Symfony\Component\Routing\Router->Symfony\Component\Routing\{closure}(object(ResourceCheckerConfigCache))
     (/var/www/html/vendor/symfony/config/ResourceCheckerConfigCacheFactory.php:34)
  at Symfony\Component\Config\ResourceCheckerConfigCacheFactory->cache('/var/www/html/var/cache/dev/url_matching_routes.php', object(Closure))
     (/var/www/html/vendor/symfony/routing/Router.php:216)
  at Symfony\Component\Routing\Router->getMatcher()
     (/var/www/html/vendor/symfony/routing/Router.php:182)
  at Symfony\Component\Routing\Router->matchRequest(object(Request))
     (/var/www/html/vendor/symfony/http-kernel/EventListener/RouterListener.php:101)
  at Symfony\Component\HttpKernel\EventListener\RouterListener->onKernelRequest(object(RequestEvent), 'kernel.request', object(TraceableEventDispatcher))
     (/var/www/html/vendor/symfony/event-dispatcher/Debug/WrappedListener.php:115)
  at Symfony\Component\EventDispatcher\Debug\WrappedListener->__invoke(object(RequestEvent), 'kernel.request', object(TraceableEventDispatcher))
     (/var/www/html/vendor/symfony/event-dispatcher/EventDispatcher.php:206)
  at Symfony\Component\EventDispatcher\EventDispatcher->callListeners(array(object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener), object(WrappedListener)), 'kernel.request', object(RequestEvent))
     (/var/www/html/vendor/symfony/event-dispatcher/EventDispatcher.php:56)
  at Symfony\Component\EventDispatcher\EventDispatcher->dispatch(object(RequestEvent), 'kernel.request')
     (/var/www/html/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php:126)
  at Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher->dispatch(object(RequestEvent), 'kernel.request')
     (/var/www/html/vendor/symfony/http-kernel/HttpKernel.php:159)
  at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
     (/var/www/html/vendor/symfony/http-kernel/HttpKernel.php:76)
  at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
     (/var/www/html/vendor/symfony/http-kernel/Kernel.php:182)
  at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
     (/var/www/html/vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php:35)
  at Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner->run()
     (/var/www/html/vendor/autoload_runtime.php:29)
  at require_once('/var/www/html/vendor/autoload_runtime.php')
     (/var/www/html/public/index.php:7)                

How to reproduce

Reproduce is simple as adding:

yield [Type::list(Type::arrayShape(['value' => Type::nullable(Type::string()), 'header' => Type::string()])), 'list<array{value: scalar|null, header: string}>'];

to src/Symfony/Component/TypeInfo/Tests/TypeResolver/StringTypeResolverTest.php::resolveDataProvider

Possible Solution

Not sure. But it should work with "scalar" as previously, unless there is a reason?

Additional Context

What's strange that StringTypeResolverTest also fails when changing scalar just to string|int|null with same error:
Cannot set "Symfony\Component\TypeInfo\Type\UnionType" as a "Symfony\Component\TypeInfo\Type\UnionType" part.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions