Skip to content

[TypeInfo] Introduce component #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 23 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9854346
[HttpKernel] Fix PHP deprecation
nicolas-grekas Nov 7, 2023
2cd1e97
bug #52488 [HttpKernel] Fix PHP deprecation (nicolas-grekas)
derrabus Nov 7, 2023
00aaea2
check that the secret passed to RequestParser is not empty
xabbuh Nov 8, 2023
8fed2d9
Accept mixed key on DsPairStub
marc-mabe Nov 8, 2023
caf41fc
minor #52497 [Webhook] check that the secret passed to RequestParser …
nicolas-grekas Nov 8, 2023
aa20487
Set exception code to ldap error number
johannes85 Nov 8, 2023
33721f5
[HttpKernel] Fix DebugLoggerConfigurator
nicolas-grekas Nov 8, 2023
86898a6
[HttpKernel] Check controllers are allowed when using the fallback su…
nicolas-grekas Nov 8, 2023
132d8e4
minor #52500 [HttpKernel] Fix DebugLoggerConfigurator (nicolas-grekas)
nicolas-grekas Nov 9, 2023
1984b96
minor #52501 [HttpKernel] Check controllers are allowed when using th…
nicolas-grekas Nov 9, 2023
08a27c2
[String] Method toByteString conversion using iconv is unreachable
Vincentv92 Nov 7, 2023
0ff9ed4
bug #52491 [String] Method toByteString conversion using iconv is unr…
nicolas-grekas Nov 9, 2023
9e8db58
[Config] Prefixing FileExistenceResource::__toString() to avoid confl…
weaverryan Nov 8, 2023
9b2c2a4
bug #52502 [Config] Prefixing `FileExistenceResource::__toString()` t…
nicolas-grekas Nov 9, 2023
3922e80
bug #52496 [VarDumper] Accept mixed key on `DsPairStub` (marc-mabe)
nicolas-grekas Nov 9, 2023
f04ea7c
minor #52498 [Ldap] Set exception code to ldap error number (johannes85)
nicolas-grekas Nov 9, 2023
54398ed
Merge branch '5.4' into 6.3
nicolas-grekas Nov 9, 2023
32ff2cd
Merge branch '6.3' into 6.4
nicolas-grekas Nov 9, 2023
58997d6
Merge branch '6.4' into 7.0
nicolas-grekas Nov 9, 2023
b95f7fc
remove error handler not needed on PHP 8
xabbuh Nov 9, 2023
1ec29ce
minor #52505 [String] remove error handler not needed on PHP 8 (xabbuh)
nicolas-grekas Nov 9, 2023
6867843
Merge branch '6.4' into 7.0
nicolas-grekas Nov 9, 2023
df1c8e9
[TypeInfo] Introduce component
mtarld Oct 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
"symfony/translation": "self.version",
"symfony/twig-bridge": "self.version",
"symfony/twig-bundle": "self.version",
"symfony/type-info": "self.version",
"symfony/uid": "self.version",
"symfony/validator": "self.version",
"symfony/var-dumper": "self.version",
Expand Down
5 changes: 5 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
CHANGELOG
=========

7.1
---

* Register TypeInfo services

7.0
---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class UnusedTagsPass implements CompilerPassInterface
'mime.mime_type_guesser',
'monolog.logger',
'notifier.channel',
'type_info.resolver',
'property_info.access_extractor',
'property_info.initializable_extractor',
'property_info.list_extractor',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
use Symfony\Component\Serializer\Encoder\JsonDecode;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Translation\Translator;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\Uid\Factory\UuidFactory;
use Symfony\Component\Validator\Validation;
use Symfony\Component\Webhook\Controller\WebhookController;
Expand Down Expand Up @@ -158,6 +159,7 @@ public function getConfigTreeBuilder(): TreeBuilder
$this->addAnnotationsSection($rootNode);
$this->addSerializerSection($rootNode, $enableIfStandalone);
$this->addPropertyAccessSection($rootNode, $willBeAvailable);
$this->addTypeInfoSection($rootNode, $enableIfStandalone);
$this->addPropertyInfoSection($rootNode, $enableIfStandalone);
$this->addCacheSection($rootNode, $willBeAvailable);
$this->addPhpErrorsSection($rootNode);
Expand Down Expand Up @@ -1148,6 +1150,18 @@ private function addPropertyInfoSection(ArrayNodeDefinition $rootNode, callable
;
}

private function addTypeInfoSection(ArrayNodeDefinition $rootNode, callable $enableIfStandalone): void
{
$rootNode
->children()
->arrayNode('type_info')
->info('Type info configuration')
->{$enableIfStandalone('symfony/type-info', Type::class)}()
->end()
->end()
;
}

private function addCacheSection(ArrayNodeDefinition $rootNode, callable $willBeAvailable): void
{
$rootNode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@
use Symfony\Component\Translation\LocaleSwitcher;
use Symfony\Component\Translation\PseudoLocalizationTranslator;
use Symfony\Component\Translation\Translator;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\TypeInfo\TypeResolver\StringTypeResolver;
use Symfony\Component\Uid\Factory\UuidFactory;
use Symfony\Component\Uid\UuidV4;
use Symfony\Component\Validator\Constraints\ExpressionLanguageProvider;
Expand Down Expand Up @@ -388,6 +390,10 @@ public function load(array $configs, ContainerBuilder $container): void
$container->removeDefinition('console.command.serializer_debug');
}

if ($this->readConfigEnabled('type_info', $container, $config['type_info'])) {
$this->registerTypeInfoConfiguration($container, $loader);
}

if ($propertyInfoEnabled) {
$this->registerPropertyInfoConfiguration($container, $loader);
}
Expand Down Expand Up @@ -1950,6 +1956,22 @@ private function registerPropertyInfoConfiguration(ContainerBuilder $container,
}
}

private function registerTypeInfoConfiguration(ContainerBuilder $container, PhpFileLoader $loader): void
{
if (!class_exists(Type::class)) {
throw new LogicException('TypeInfo support cannot be enabled as the TypeInfo component is not installed. Try running "composer require symfony/type-info".');
}

$loader->load('type_info.php');

if (ContainerBuilder::willBeAvailable('phpstan/phpdoc-parser', PhpDocParser::class, ['symfony/framework-bundle', 'symfony/type-info'])) {
$container->register('type_info.resolver.string', StringTypeResolver::class)
->addTag('type_info.resolver', ['priority' => -1000]);

$container->setAlias(StringTypeResolver::class, 'type_info.resolver.string');
}
}

private function registerLockConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader): void
{
$loader->load('lock.php');
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
use Symfony\Component\Translation\DependencyInjection\TranslationExtractorPass;
use Symfony\Component\Translation\DependencyInjection\TranslatorPass;
use Symfony\Component\Translation\DependencyInjection\TranslatorPathsPass;
use Symfony\Component\TypeInfo\DependencyInjection\TypeInfoPass;
use Symfony\Component\Validator\DependencyInjection\AddAutoMappingConfigurationPass;
use Symfony\Component\Validator\DependencyInjection\AddConstraintValidatorsPass;
use Symfony\Component\Validator\DependencyInjection\AddValidatorInitializersPass;
Expand Down Expand Up @@ -150,6 +151,7 @@ public function build(ContainerBuilder $container): void
$this->addCompilerPassIfExists($container, TranslationDumperPass::class);
$container->addCompilerPass(new FragmentRendererPass());
$this->addCompilerPassIfExists($container, SerializerPass::class);
$this->addCompilerPassIfExists($container, TypeInfoPass::class);
$this->addCompilerPassIfExists($container, PropertyInfoPass::class);
$container->addCompilerPass(new ControllerArgumentValueResolverPass());
$container->addCompilerPass(new CachePoolPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 32);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<xsd:element name="property-access" type="property_access" minOccurs="0" maxOccurs="1" />
<xsd:element name="scheduler" type="scheduler" minOccurs="0" maxOccurs="1" />
<xsd:element name="serializer" type="serializer" minOccurs="0" maxOccurs="1" />
<xsd:element name="type-info" type="type_info" minOccurs="0" maxOccurs="1" />
<xsd:element name="property-info" type="property_info" minOccurs="0" maxOccurs="1" />
<xsd:element name="cache" type="cache" minOccurs="0" maxOccurs="1" />
<xsd:element name="workflow" type="workflow" minOccurs="0" maxOccurs="unbounded" />
Expand Down Expand Up @@ -326,6 +327,10 @@
<xsd:attribute name="max-depth-handler" type="xsd:string" />
</xsd:complexType>

<xsd:complexType name="type_info">
<xsd:attribute name="enabled" type="xsd:boolean" />
</xsd:complexType>

<xsd:complexType name="property_info">
<xsd:attribute name="enabled" type="xsd:boolean" />
</xsd:complexType>
Expand Down
53 changes: 53 additions & 0 deletions src/Symfony/Bundle/FrameworkBundle/Resources/config/type_info.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\DependencyInjection\Loader\Configurator;

use Symfony\Component\TypeInfo\TypeContext\TypeContextFactory;
use Symfony\Component\TypeInfo\TypeResolver\ChainTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\ReflectionParameterTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\ReflectionPropertyTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\ReflectionReturnTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\ReflectionTypeResolver;
use Symfony\Component\TypeInfo\TypeResolver\TypeResolverInterface;

return static function (ContainerConfigurator $container) {
$container->services()
// type context
->set('type_info.type_context_factory', TypeContextFactory::class)
->args([service('type_info.resolver.string')->nullOnInvalid()])

// type resolvers
->set('type_info.resolver', ChainTypeResolver::class)
->args([[]])
->alias(TypeResolverInterface::class, 'type_info.resolver')

->set('type_info.resolver.reflection_type', ReflectionTypeResolver::class)
->args([service('type_info.type_context_factory')])
->tag('type_info.resolver', ['priority' => -1001])
->alias(ReflectionTypeResolver::class, 'type_info.resolver.reflection_type')

->set('type_info.resolver.reflection_parameter', ReflectionParameterTypeResolver::class)
->args([service('type_info.resolver.reflection_type'), service('type_info.type_context_factory')])
->tag('type_info.resolver', ['priority' => -1002])
->alias(ReflectionParameterTypeResolver::class, 'type_info.resolver.reflection_parameter')

->set('type_info.resolver.reflection_property', ReflectionPropertyTypeResolver::class)
->args([service('type_info.resolver.reflection_type'), service('type_info.type_context_factory')])
->tag('type_info.resolver', ['priority' => -1003])
->alias(ReflectionPropertyTypeResolver::class, 'type_info.resolver.reflection_property')

->set('type_info.resolver.reflection_return', ReflectionReturnTypeResolver::class)
->args([service('type_info.resolver.reflection_type'), service('type_info.type_context_factory')])
->tag('type_info.resolver', ['priority' => -1004])
->alias(ReflectionReturnTypeResolver::class, 'type_info.resolver.reflection_return')
;
};
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Symfony\Component\RateLimiter\Policy\TokenBucketLimiter;
use Symfony\Component\Scheduler\Messenger\SchedulerTransportFactory;
use Symfony\Component\Serializer\Encoder\JsonDecode;
use Symfony\Component\TypeInfo\Type;
use Symfony\Component\Uid\Factory\UuidFactory;

class ConfigurationTest extends TestCase
Expand Down Expand Up @@ -623,6 +624,9 @@ protected static function getBundleDefaultConfig()
'throw_exception_on_invalid_index' => false,
'throw_exception_on_invalid_property_path' => true,
],
'type_info' => [
'enabled' => !class_exists(FullStack::class) && class_exists(Type::class),
],
'property_info' => [
'enabled' => !class_exists(FullStack::class),
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
'default_context' => ['enable_max_depth' => true],
],
'property_info' => true,
'type_info' => true,
'ide' => 'file%%link%%format',
'request' => [
'formats' => [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

$container->loadFromExtension('framework', [
'annotations' => false,
'http_method_override' => false,
'handle_all_throwables' => true,
'php_errors' => ['log' => true],
'type_info' => [
'enabled' => true,
],
]);
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@
</framework:default-context>
</framework:serializer>
<framework:property-info />
<framework:type-info />
</framework:config>
</container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">

<framework:config http-method-override="false" handle-all-throwables="true">
<framework:annotations enabled="false" />
<framework:php-errors log="true" />
<framework:type-info enabled="true" />
</framework:config>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ framework:
max_depth_handler: my.max.depth.handler
default_context:
enable_max_depth: true
type_info: ~
property_info: ~
ide: file%%link%%format
request:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
framework:
annotations: false
http_method_override: false
handle_all_throwables: true
php_errors:
log: true
type_info:
enabled: true
Original file line number Diff line number Diff line change
Expand Up @@ -1608,6 +1608,12 @@ public function testSerializerServiceIsNotRegisteredWhenDisabled()
$this->assertFalse($container->hasDefinition('serializer'));
}

public function testTypeInfoEnabled()
{
$container = $this->createContainerFromFile('type_info');
$this->assertTrue($container->has('type_info.resolver'));
}

public function testPropertyInfoEnabled()
{
$container = $this->createContainerFromFile('property_info');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\FrameworkBundle\Tests\Functional;

use Symfony\Component\TypeInfo\Type;

class TypeInfoTest extends AbstractWebTestCase
{
public function testComponent()
{
static::bootKernel(['test_case' => 'TypeInfo']);

$this->assertEquals(Type::union(Type::int(), Type::null()), static::getContainer()->get('type_info.resolver')->resolve('int|null'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\Tests\Functional\Bundle\TestBundle\TestBundle;

return [
new FrameworkBundle(),
new TestBundle(),
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
imports:
- { resource: ../config/default.yml }

framework:
http_method_override: false
type_info: true

services:
type_info.resolver.alias:
alias: type_info.resolver
public: true
1 change: 1 addition & 0 deletions src/Symfony/Bundle/FrameworkBundle/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
"symfony/string": "^6.4|^7.0",
"symfony/translation": "^6.4|^7.0",
"symfony/twig-bundle": "^6.4|^7.0",
"symfony/type-info": "^7.1",
"symfony/validator": "^6.4|^7.0",
"symfony/workflow": "^6.4|^7.0",
"symfony/yaml": "^6.4|^7.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function __construct(string $resource)

public function __toString(): string
{
return $this->resource;
return 'existence.'.$this->resource;
}

public function getResource(): string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected function tearDown(): void

public function testToString()
{
$this->assertSame($this->file, (string) $this->resource);
$this->assertSame('existence.'.$this->file, (string) $this->resource);
}

public function testGetResource()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,12 +268,6 @@ private function checkController(Request $request, callable $controller): callab
$name = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', fn ($m) => class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0], $name);
}

if (-1 === $request->attributes->get('_check_controller_is_allowed')) {
trigger_deprecation('symfony/http-kernel', '6.4', 'Callable "%s()" is not allowed as a controller. Did you miss tagging it with "#[AsController]" or registering its type with "%s::allowControllers()"?', $name, self::class);

return $controller;
}

throw new BadRequestException(sprintf('Callable "%s()" is not allowed as a controller. Did you miss tagging it with "#[AsController]" or registering its type with "%s::allowControllers()"?', $name, self::class));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ private function getContainerDeprecationLogs(): array

private function getContainerCompilerLogs(string $compilerLogsFilepath = null): array
{
if (!is_file($compilerLogsFilepath)) {
if (!$compilerLogsFilepath || !is_file($compilerLogsFilepath)) {
return [];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function onKernelRequest(RequestEvent $event): void
}

parse_str($request->query->get('_path', ''), $attributes);
$attributes['_check_controller_is_allowed'] = -1; // @deprecated, switch to true in Symfony 7
$attributes['_check_controller_is_allowed'] = true;
$request->attributes->add($attributes);
$request->attributes->set('_route_params', array_replace($request->attributes->get('_route_params', []), $attributes));
$request->query->remove('_path');
Expand Down
Loading