From 51a14b1148b582a103823e410c66147b63b3fe58 Mon Sep 17 00:00:00 2001 From: karser Date: Sat, 9 Feb 2019 23:17:36 +0200 Subject: [PATCH 1/3] Added ConstructorExtractor which has higher priority than PhpDocExtractor and ReflectionExtractor --- .../FrameworkExtension.php | 1 + .../FrameworkBundle/FrameworkBundle.php | 2 + .../Resources/config/property_info.xml | 6 ++ .../Tests/Functional/PropertyInfoTest.php | 22 ++++++ .../PropertyInfoConstructorPass.php | 50 +++++++++++++ ...structorArgumentTypeExtractorInterface.php | 32 ++++++++ .../Extractor/ConstructorExtractor.php | 48 ++++++++++++ .../Extractor/PhpDocExtractor.php | 73 ++++++++++++++++++- .../Extractor/ReflectionExtractor.php | 48 +++++++++++- .../PropertyInfoConstructorPassTest.php | 54 ++++++++++++++ .../Extractor/ConstructorExtractorTest.php | 40 ++++++++++ .../Tests/Extractor/PhpDocExtractorTest.php | 19 +++++ .../Extractor/ReflectionExtractorTest.php | 19 +++++ .../Tests/Fixtures/ConstructorDummy.php | 30 ++++++++ .../Tests/Fixtures/DummyExtractor.php | 11 ++- 15 files changed, 452 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Component/PropertyInfo/DependencyInjection/PropertyInfoConstructorPass.php create mode 100644 src/Symfony/Component/PropertyInfo/Extractor/ConstructorArgumentTypeExtractorInterface.php create mode 100644 src/Symfony/Component/PropertyInfo/Extractor/ConstructorExtractor.php create mode 100644 src/Symfony/Component/PropertyInfo/Tests/DependencyInjection/PropertyInfoConstructorPassTest.php create mode 100644 src/Symfony/Component/PropertyInfo/Tests/Extractor/ConstructorExtractorTest.php create mode 100644 src/Symfony/Component/PropertyInfo/Tests/Fixtures/ConstructorDummy.php diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 87ce95e44bc13..cad267ccd8eae 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -1413,6 +1413,7 @@ private function registerPropertyInfoConfiguration(ContainerBuilder $container, $definition->setPrivate(true); $definition->addTag('property_info.description_extractor', ['priority' => -1000]); $definition->addTag('property_info.type_extractor', ['priority' => -1001]); + $definition->addTag('property_info.constructor_extractor', ['priority' => -1001]); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php index 999f4aed36f96..1306a9bb7ef54 100644 --- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php +++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php @@ -44,6 +44,7 @@ use Symfony\Component\HttpKernel\DependencyInjection\ResettableServicePass; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Messenger\DependencyInjection\MessengerPass; +use Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoConstructorPass; use Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass; use Symfony\Component\Routing\DependencyInjection\RoutingResolverPass; use Symfony\Component\Serializer\DependencyInjection\SerializerPass; @@ -107,6 +108,7 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new FragmentRendererPass()); $this->addCompilerPassIfExists($container, SerializerPass::class); $this->addCompilerPassIfExists($container, PropertyInfoPass::class); + $this->addCompilerPassIfExists($container, PropertyInfoConstructorPass::class); $container->addCompilerPass(new DataCollectorTranslatorPass()); $container->addCompilerPass(new ControllerArgumentValueResolverPass()); $container->addCompilerPass(new CachePoolPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 32); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml index e8778f70822bf..925cc62f3bea1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml @@ -25,8 +25,14 @@ + + + + + + diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/PropertyInfoTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/PropertyInfoTest.php index 61669e90adbc7..66594ba2c3229 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/PropertyInfoTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/PropertyInfoTest.php @@ -11,6 +11,7 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\PropertyInfo\Type; class PropertyInfoTest extends WebTestCase @@ -21,6 +22,27 @@ public function testPhpDocPriority() $this->assertEquals([new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), new Type(Type::BUILTIN_TYPE_INT))], static::$container->get('property_info')->getTypes('Symfony\Bundle\FrameworkBundle\Tests\Functional\Dummy', 'codes')); } + + /** + * @dataProvider constructorOverridesPropertyTypeProvider + */ + public function testConstructorOverridesPropertyType($property, array $type = null) + { + static::bootKernel(['test_case' => 'Serializer']); + $extractor = static::$container->get('property_info'); + $this->assertEquals($type, $extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\ConstructorDummy', $property)); + } + + public function constructorOverridesPropertyTypeProvider() + { + return [ + ['timezone', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTimeZone')]], + ['date', [new Type(Type::BUILTIN_TYPE_INT)]], + ['dateObject', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTimeInterface')]], + ['dateTime', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime')]], + ['ddd', null], + ]; + } } class Dummy diff --git a/src/Symfony/Component/PropertyInfo/DependencyInjection/PropertyInfoConstructorPass.php b/src/Symfony/Component/PropertyInfo/DependencyInjection/PropertyInfoConstructorPass.php new file mode 100644 index 0000000000000..ccf84e82faa3c --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/DependencyInjection/PropertyInfoConstructorPass.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyInfo\DependencyInjection; + +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; +use Symfony\Component\DependencyInjection\ContainerBuilder; + +/** + * Adds extractors to the property_info.constructor_extractor service. + * + * @author Dmitrii Poddubnyi + */ +class PropertyInfoConstructorPass implements CompilerPassInterface +{ + use PriorityTaggedServiceTrait; + + private $service; + private $tag; + + public function __construct($service = 'property_info.constructor_extractor', $tag = 'property_info.constructor_extractor') + { + $this->service = $service; + $this->tag = $tag; + } + + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + if (!$container->hasDefinition($this->service)) { + return; + } + $definition = $container->getDefinition($this->service); + + $listExtractors = $this->findAndSortTaggedServices($this->tag, $container); + $definition->replaceArgument(0, new IteratorArgument($listExtractors)); + } +} diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ConstructorArgumentTypeExtractorInterface.php b/src/Symfony/Component/PropertyInfo/Extractor/ConstructorArgumentTypeExtractorInterface.php new file mode 100644 index 0000000000000..3192b79fb0646 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Extractor/ConstructorArgumentTypeExtractorInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyInfo\Extractor; + +use Symfony\Component\PropertyInfo\Type; + +/** + * Infers the constructor argument type. + * + * @author Dmitrii Poddubnyi + */ +interface ConstructorArgumentTypeExtractorInterface +{ + /** + * Gets types of an argument from constructor. + * + * @param string $class + * @param string $property + * + * @return Type[]|null + */ + public function getTypesFromConstructor($class, $property); +} diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ConstructorExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ConstructorExtractor.php new file mode 100644 index 0000000000000..9695523bc050a --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Extractor/ConstructorExtractor.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyInfo\Extractor; + +use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface; + +/** + * Extracts the constructor argument type using ConstructorArgumentTypeExtractorInterface implementations. + * + * @author Dmitrii Poddubnyi + */ +class ConstructorExtractor implements PropertyTypeExtractorInterface +{ + /** @var iterable|ConstructorArgumentTypeExtractorInterface[] */ + private $extractors; + + /** + * @param iterable|ConstructorArgumentTypeExtractorInterface[] $extractors + */ + public function __construct($extractors = []) + { + $this->extractors = $extractors; + } + + /** + * {@inheritdoc} + */ + public function getTypes($class, $property, array $context = []) + { + foreach ($this->extractors as $extractor) { + $value = $extractor->getTypesFromConstructor($class, $property); + if (null !== $value) { + return $value; + } + } + + return null; + } +} diff --git a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php index 4837d2200c852..1e0a401c4034b 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/PhpDocExtractor.php @@ -27,7 +27,7 @@ * * @final */ -class PhpDocExtractor implements PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface +class PhpDocExtractor implements PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface, ConstructorArgumentTypeExtractorInterface { const PROPERTY = 0; const ACCESSOR = 1; @@ -151,6 +151,77 @@ public function getTypes($class, $property, array $context = []) return [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $types[0])]; } + /** + * {@inheritdoc} + */ + public function getTypesFromConstructor($class, $property) + { + $docBlock = $this->getDocBlockFromConstructor($class, $property); + + if (!$docBlock) { + return; + } + + $types = []; + /** @var DocBlock\Tags\Var_|DocBlock\Tags\Return_|DocBlock\Tags\Param $tag */ + foreach ($docBlock->getTagsByName('param') as $tag) { + if ($tag && null !== $tag->getType()) { + $types = array_merge($types, $this->phpDocTypeHelper->getTypes($tag->getType())); + } + } + + if (!isset($types[0])) { + return; + } + + return $types; + } + + /** + * Gets the DocBlock from a constructor. + * + * @param string $class + * @param string $property + * + * @return DocBlock|null + */ + private function getDocBlockFromConstructor($class, $property) + { + try { + $reflectionClass = new \ReflectionClass($class); + } catch (\ReflectionException $e) { + return null; + } + $reflectionConstructor = $reflectionClass->getConstructor(); + if (!$reflectionConstructor) { + return null; + } + + try { + $docBlock = $this->docBlockFactory->create($reflectionConstructor, $this->contextFactory->createFromReflector($reflectionConstructor)); + + return $this->filterDocBlockParams($docBlock, $property); + } catch (\InvalidArgumentException $e) { + return null; + } + } + + /** + * @param DocBlock $docBlock + * @param string $allowedParam + * + * @return DocBlock + */ + private function filterDocBlockParams(DocBlock $docBlock, $allowedParam) + { + $tags = array_values(array_filter($docBlock->getTagsByName('param'), function ($tag) use ($allowedParam) { + return $tag instanceof DocBlock\Tags\Param && $allowedParam === $tag->getVariableName(); + })); + + return new DocBlock($docBlock->getSummary(), $docBlock->getDescription(), $tags, $docBlock->getContext(), + $docBlock->getLocation(), $docBlock->isTemplateStart(), $docBlock->isTemplateEnd()); + } + private function getDocBlock(string $class, string $property): array { $propertyHash = sprintf('%s::%s', $class, $property); diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index 0ed1e4e2afe3d..ce6608c22405a 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -25,7 +25,7 @@ * * @final */ -class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface, PropertyInitializableExtractorInterface +class ReflectionExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface, PropertyInitializableExtractorInterface, ConstructorArgumentTypeExtractorInterface { /** * @internal @@ -119,6 +119,52 @@ public function getTypes($class, $property, array $context = []) } } + + /** + * {@inheritdoc} + */ + public function getTypesFromConstructor($class, $property) + { + try { + $reflection = new \ReflectionClass($class); + } catch (\ReflectionException $e) { + return null; + } + if (!$reflectionConstructor = $reflection->getConstructor()) { + return null; + } + if (!$reflectionParameter = $this->getReflectionParameterFromConstructor($property, $reflectionConstructor)) { + return null; + } + if (!$reflectionType = $reflectionParameter->getType()) { + return null; + } + if (!$type = $this->extractFromReflectionType($reflectionType, $reflectionConstructor)) { + return null; + } + + return [$type]; + } + + /** + * @param string $property + * @param \ReflectionMethod $reflectionConstructor + * + * @return \ReflectionParameter|null + */ + private function getReflectionParameterFromConstructor($property, \ReflectionMethod $reflectionConstructor) + { + $reflectionParameter = null; + foreach ($reflectionConstructor->getParameters() as $reflectionParameter) { + if ($reflectionParameter->getName() === $property) { + return $reflectionParameter; + } + } + + return null; + } + + /** * {@inheritdoc} */ diff --git a/src/Symfony/Component/PropertyInfo/Tests/DependencyInjection/PropertyInfoConstructorPassTest.php b/src/Symfony/Component/PropertyInfo/Tests/DependencyInjection/PropertyInfoConstructorPassTest.php new file mode 100644 index 0000000000000..ee3151f2710a9 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/DependencyInjection/PropertyInfoConstructorPassTest.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\PropertyInfo\Tests\DependencyInjection; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Argument\IteratorArgument; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoConstructorPass; + +class PropertyInfoConstructorPassTest extends TestCase +{ + public function testServicesAreOrderedAccordingToPriority() + { + $container = new ContainerBuilder(); + + $tag = 'property_info.constructor_extractor'; + $definition = $container->register('property_info.constructor_extractor')->setArguments([null, null]); + $container->register('n2')->addTag($tag, ['priority' => 100]); + $container->register('n1')->addTag($tag, ['priority' => 200]); + $container->register('n3')->addTag($tag); + + $pass = new PropertyInfoConstructorPass(); + $pass->process($container); + + $expected = new IteratorArgument([ + new Reference('n1'), + new Reference('n2'), + new Reference('n3'), + ]); + $this->assertEquals($expected, $definition->getArgument(0)); + } + + public function testReturningEmptyArrayWhenNoService() + { + $container = new ContainerBuilder(); + $propertyInfoExtractorDefinition = $container->register('property_info.constructor_extractor') + ->setArguments([[]]); + + $pass = new PropertyInfoConstructorPass(); + $pass->process($container); + + $this->assertEquals(new IteratorArgument([]), $propertyInfoExtractorDefinition->getArgument(0)); + } +} diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ConstructorExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ConstructorExtractorTest.php new file mode 100644 index 0000000000000..11a28c0f7c824 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ConstructorExtractorTest.php @@ -0,0 +1,40 @@ + + */ +class ConstructorExtractorTest extends TestCase +{ + /** + * @var ConstructorExtractor + */ + private $extractor; + + protected function setUp() + { + $this->extractor = new ConstructorExtractor([new DummyExtractor()]); + } + + public function testInstanceOf() + { + $this->assertInstanceOf('Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface', $this->extractor); + } + + public function testGetTypes() + { + $this->assertEquals([new Type(Type::BUILTIN_TYPE_STRING)], $this->extractor->getTypes('Foo', 'bar', [])); + } + + public function testGetTypes_ifNoExtractors() + { + $extractor = new ConstructorExtractor([]); + $this->assertNull($extractor->getTypes('Foo', 'bar', [])); + } +} diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php index 930dc6e24c9b8..33280e79032dd 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/PhpDocExtractorTest.php @@ -247,6 +247,25 @@ public function testDocBlockFallback($property, $types) { $this->assertEquals($types, $this->extractor->getTypes('Symfony\Component\PropertyInfo\Tests\Fixtures\DockBlockFallback', $property)); } + + /** + * @dataProvider constructorTypesProvider + */ + public function testExtractConstructorTypes($property, array $type = null) + { + $this->assertEquals($type, $this->extractor->getTypesFromConstructor('Symfony\Component\PropertyInfo\Tests\Fixtures\ConstructorDummy', $property)); + } + + public function constructorTypesProvider() + { + return [ + ['date', [new Type(Type::BUILTIN_TYPE_INT)]], + ['timezone', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTimeZone')]], + ['dateObject', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTimeInterface')]], + ['dateTime', null], + ['ddd', null], + ]; + } } class EmptyDocBlock diff --git a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php index e58c70d41d702..cb5e02ceb0d5b 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Extractor/ReflectionExtractorTest.php @@ -293,4 +293,23 @@ public function getInitializableProperties(): array [NotInstantiable::class, 'foo', false], ]; } + + /** + * @dataProvider constructorTypesProvider + */ + public function testExtractConstructorTypes($property, array $type = null) + { + $this->assertEquals($type, $this->extractor->getTypesFromConstructor('Symfony\Component\PropertyInfo\Tests\Fixtures\ConstructorDummy', $property)); + } + + public function constructorTypesProvider() + { + return [ + ['timezone', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTimeZone')]], + ['date', null], + ['dateObject', null], + ['dateTime', [new Type(Type::BUILTIN_TYPE_OBJECT, false, 'DateTime')]], + ['ddd', null], + ]; + } } diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ConstructorDummy.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ConstructorDummy.php new file mode 100644 index 0000000000000..23ef5cceaef75 --- /dev/null +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/ConstructorDummy.php @@ -0,0 +1,30 @@ + + */ +class ConstructorDummy +{ + /** @var string */ + private $timezone; + + /** @var \DateTimeInterface */ + private $date; + + /** @var int */ + private $dateTime; + + /** + * @param \DateTimeZone $timezone + * @param int $date Timestamp + * @param \DateTimeInterface $dateObject + */ + public function __construct(\DateTimeZone $timezone, $date, $dateObject, \DateTime $dateTime) + { + $this->timezone = $timezone->getName(); + $this->date = \DateTime::createFromFormat('U', $date); + $this->dateTime = $dateTime->getTimestamp(); + } +} diff --git a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyExtractor.php b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyExtractor.php index 9003b2fa38a6d..d75f1bc0d388f 100644 --- a/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyExtractor.php @@ -11,6 +11,7 @@ namespace Symfony\Component\PropertyInfo\Tests\Fixtures; +use Symfony\Component\PropertyInfo\Extractor\ConstructorArgumentTypeExtractorInterface; use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface; use Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface; use Symfony\Component\PropertyInfo\PropertyInitializableExtractorInterface; @@ -21,7 +22,7 @@ /** * @author Kévin Dunglas */ -class DummyExtractor implements PropertyListExtractorInterface, PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface, PropertyInitializableExtractorInterface +class DummyExtractor implements PropertyListExtractorInterface, PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface, PropertyInitializableExtractorInterface, ConstructorArgumentTypeExtractorInterface { /** * {@inheritdoc} @@ -47,6 +48,14 @@ public function getTypes($class, $property, array $context = []) return [new Type(Type::BUILTIN_TYPE_INT)]; } + /** + * {@inheritdoc} + */ + public function getTypesFromConstructor($class, $property) + { + return [new Type(Type::BUILTIN_TYPE_STRING)]; + } + /** * {@inheritdoc} */ From fd1689e9b6e67e008f1c972123b10e7c54cf846c Mon Sep 17 00:00:00 2001 From: karser Date: Sat, 9 Feb 2019 23:29:38 +0200 Subject: [PATCH 2/3] fabbot.io compliance --- .../FrameworkBundle/Tests/Functional/PropertyInfoTest.php | 1 - .../Component/PropertyInfo/Extractor/ReflectionExtractor.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/PropertyInfoTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/PropertyInfoTest.php index 66594ba2c3229..b654008dacb2b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/PropertyInfoTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/PropertyInfoTest.php @@ -11,7 +11,6 @@ namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\PropertyInfo\Type; class PropertyInfoTest extends WebTestCase diff --git a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php index ce6608c22405a..1543674184b5a 100644 --- a/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php +++ b/src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php @@ -119,7 +119,6 @@ public function getTypes($class, $property, array $context = []) } } - /** * {@inheritdoc} */ @@ -164,7 +163,6 @@ private function getReflectionParameterFromConstructor($property, \ReflectionMet return null; } - /** * {@inheritdoc} */ From 3efc0c64a1485ce2e0521ae2c50012b398dc9bda Mon Sep 17 00:00:00 2001 From: karser Date: Sat, 9 Feb 2019 23:48:03 +0200 Subject: [PATCH 3/3] fix supported PropertyInfo component version constraints --- src/Symfony/Bundle/FrameworkBundle/composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index e18554972e423..cf129bc336e0d 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -54,7 +54,7 @@ "symfony/var-dumper": "~3.4|~4.0", "symfony/workflow": "^4.1", "symfony/yaml": "~3.4|~4.0", - "symfony/property-info": "~3.4|~4.0", + "symfony/property-info": "~3.4.23|^4.2.4", "symfony/lock": "~3.4|~4.0", "symfony/web-link": "~3.4|~4.0", "doctrine/annotations": "~1.0", @@ -70,7 +70,7 @@ "symfony/dotenv": "<4.2", "symfony/form": "<4.2", "symfony/messenger": "<4.2", - "symfony/property-info": "<3.4", + "symfony/property-info": "<3.4.23|>=4.0.0,<4.2.4", "symfony/serializer": "<4.2", "symfony/stopwatch": "<3.4", "symfony/translation": "<4.2", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy