Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita95d0a8

Browse files
committed
[PropertyInfo] Add an extractor to guess if a property is initializable
1 parent833909b commita95d0a8

File tree

12 files changed

+158
-14
lines changed

12 files changed

+158
-14
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Resources/config/property_info.xml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<argumenttype="collection" />
1313
<argumenttype="collection" />
1414
<argumenttype="collection" />
15+
<argumenttype="collection" />
1516
</service>
1617
<serviceid="Symfony\Component\PropertyInfo\PropertyInfoExtractorInterface"alias="property_info" />
1718

@@ -20,6 +21,7 @@
2021
<tagname="property_info.list_extractor"priority="-1000" />
2122
<tagname="property_info.type_extractor"priority="-1002" />
2223
<tagname="property_info.access_extractor"priority="-1000" />
24+
<tagname="property_info.initializable_extractor"priority="-1000" />
2325
</service>
2426
</services>
2527
</container>

‎src/Symfony/Component/PropertyInfo/DependencyInjection/PropertyInfoPass.php‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,16 @@ class PropertyInfoPass implements CompilerPassInterface
3030
private$typeExtractorTag;
3131
private$descriptionExtractorTag;
3232
private$accessExtractorTag;
33+
private$initializableExtractorTag;
3334

34-
publicfunction__construct(string$propertyInfoService ='property_info',string$listExtractorTag ='property_info.list_extractor',string$typeExtractorTag ='property_info.type_extractor',string$descriptionExtractorTag ='property_info.description_extractor',string$accessExtractorTag ='property_info.access_extractor')
35+
publicfunction__construct(string$propertyInfoService ='property_info',string$listExtractorTag ='property_info.list_extractor',string$typeExtractorTag ='property_info.type_extractor',string$descriptionExtractorTag ='property_info.description_extractor',string$accessExtractorTag ='property_info.access_extractor',string$initializableExtractorTag ='property_info.initializable_extractor')
3536
{
3637
$this->propertyInfoService =$propertyInfoService;
3738
$this->listExtractorTag =$listExtractorTag;
3839
$this->typeExtractorTag =$typeExtractorTag;
3940
$this->descriptionExtractorTag =$descriptionExtractorTag;
4041
$this->accessExtractorTag =$accessExtractorTag;
42+
$this->initializableExtractorTag =$initializableExtractorTag;
4143
}
4244

4345
/**
@@ -62,5 +64,8 @@ public function process(ContainerBuilder $container)
6264

6365
$accessExtractors =$this->findAndSortTaggedServices($this->accessExtractorTag,$container);
6466
$definition->replaceArgument(3,newIteratorArgument($accessExtractors));
67+
68+
$initializableExtractors =$this->findAndSortTaggedServices($this->initializableExtractorTag,$container);
69+
$definition->replaceArgument(4,newIteratorArgument($initializableExtractors));
6570
}
6671
}

‎src/Symfony/Component/PropertyInfo/Extractor/ReflectionExtractor.php‎

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
useSymfony\Component\Inflector\Inflector;
1515
useSymfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
16+
useSymfony\Component\PropertyInfo\PropertyInitializableExtractorInterface;
1617
useSymfony\Component\PropertyInfo\PropertyListExtractorInterface;
1718
useSymfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
1819
useSymfony\Component\PropertyInfo\Type;
@@ -24,7 +25,7 @@
2425
*
2526
* @final
2627
*/
27-
class ReflectionExtractorimplements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface
28+
class ReflectionExtractorimplements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface, PropertyInitializableExtractorInterface
2829
{
2930
/**
3031
* @internal
@@ -146,6 +147,33 @@ public function isWritable($class, $property, array $context = array())
146147
returnnull !==$reflectionMethod;
147148
}
148149

150+
151+
/**
152+
* {@inheritdoc}
153+
*/
154+
publicfunctionisInitializable(string$class,string$property,array$context =array()): ?bool
155+
{
156+
try {
157+
$reflectionClass =new \ReflectionClass($class);
158+
}catch (\ReflectionException$e) {
159+
returnnull;
160+
}
161+
162+
if ($constructor =$reflectionClass->getConstructor()) {
163+
foreach ($constructor->getParameters()as$parameter) {
164+
if ($property !==$parameter->name) {
165+
continue;
166+
}
167+
168+
returntrue;
169+
}
170+
}elseif ($parentClass =$reflectionClass->getParentClass()) {
171+
return$this->isInitializable($parentClass->getName(),$property);
172+
}
173+
174+
returnfalse;
175+
}
176+
149177
/**
150178
* @return Type[]|null
151179
*/

‎src/Symfony/Component/PropertyInfo/PropertyInfoCacheExtractor.php‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*
2121
* @final
2222
*/
23-
class PropertyInfoCacheExtractorimplements PropertyInfoExtractorInterface
23+
class PropertyInfoCacheExtractorimplements PropertyInfoExtractorInterface, PropertyInitializableExtractorInterface
2424
{
2525
private$propertyInfoExtractor;
2626
private$cacheItemPool;
@@ -80,6 +80,14 @@ public function getTypes($class, $property, array $context = array())
8080
return$this->extract('getTypes',array($class,$property,$context));
8181
}
8282

83+
/**
84+
* {@inheritdoc}
85+
*/
86+
publicfunctionisInitializable(string$class,string$property,array$context =array()): ?bool
87+
{
88+
return$this->extract('isInitializable',array($class,$property,$context));
89+
}
90+
8391
/**
8492
* Retrieves the cached data if applicable or delegates to the decorated extractor.
8593
*

‎src/Symfony/Component/PropertyInfo/PropertyInfoExtractor.php‎

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,28 @@
1818
*
1919
* @final
2020
*/
21-
class PropertyInfoExtractorimplements PropertyInfoExtractorInterface
21+
class PropertyInfoExtractorimplements PropertyInfoExtractorInterface, PropertyInitializableExtractorInterface
2222
{
2323
private$listExtractors;
2424
private$typeExtractors;
2525
private$descriptionExtractors;
2626
private$accessExtractors;
27+
private$initializableExtractors;
2728

2829
/**
29-
* @param iterable|PropertyListExtractorInterface[] $listExtractors
30-
* @param iterable|PropertyTypeExtractorInterface[] $typeExtractors
31-
* @param iterable|PropertyDescriptionExtractorInterface[] $descriptionExtractors
32-
* @param iterable|PropertyAccessExtractorInterface[] $accessExtractors
30+
* @param iterable|PropertyListExtractorInterface[] $listExtractors
31+
* @param iterable|PropertyTypeExtractorInterface[] $typeExtractors
32+
* @param iterable|PropertyDescriptionExtractorInterface[] $descriptionExtractors
33+
* @param iterable|PropertyAccessExtractorInterface[] $accessExtractors
34+
* @param iterable|PropertyInitializableExtractorInterface[] $initializableExtractors
3335
*/
34-
publicfunction__construct(iterable$listExtractors =array(),iterable$typeExtractors =array(),iterable$descriptionExtractors =array(),iterable$accessExtractors =array())
36+
publicfunction__construct(iterable$listExtractors =array(),iterable$typeExtractors =array(),iterable$descriptionExtractors =array(),iterable$accessExtractors =array(),iterable$initializableExtractors =array())
3537
{
3638
$this->listExtractors =$listExtractors;
3739
$this->typeExtractors =$typeExtractors;
3840
$this->descriptionExtractors =$descriptionExtractors;
3941
$this->accessExtractors =$accessExtractors;
42+
$this->initializableExtractors =$initializableExtractors;
4043
}
4144

4245
/**
@@ -87,6 +90,14 @@ public function isWritable($class, $property, array $context = array())
8790
return$this->extract($this->accessExtractors,'isWritable',array($class,$property,$context));
8891
}
8992

93+
/**
94+
* {@inheritdoc}
95+
*/
96+
publicfunctionisInitializable(string$class,string$property,array$context =array()): ?bool
97+
{
98+
return$this->extract($this->initializableExtractors,'isInitializable',array($class,$property,$context));
99+
}
100+
90101
/**
91102
* Iterates over registered extractors and return the first value found.
92103
*
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\PropertyInfo;
13+
14+
/**
15+
* Guesses if the property can be initialized through the constructor.
16+
*
17+
* @author Kévin Dunglas <dunglas@gmail.com>
18+
*/
19+
interface PropertyInitializableExtractorInterface
20+
{
21+
/**
22+
* Is the property initializable?
23+
*/
24+
publicfunctionisInitializable(string$class,string$property,array$context =array()): ?bool;
25+
}

‎src/Symfony/Component/PropertyInfo/Tests/AbstractPropertyInfoExtractorTest.php‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
usePHPUnit\Framework\TestCase;
1515
useSymfony\Component\PropertyInfo\PropertyInfoExtractor;
16+
useSymfony\Component\PropertyInfo\PropertyInitializableExtractorInterface;
1617
useSymfony\Component\PropertyInfo\Tests\Fixtures\DummyExtractor;
1718
useSymfony\Component\PropertyInfo\Tests\Fixtures\NullExtractor;
1819
useSymfony\Component\PropertyInfo\Type;
@@ -30,7 +31,7 @@ class AbstractPropertyInfoExtractorTest extends TestCase
3031
protectedfunctionsetUp()
3132
{
3233
$extractors =array(newNullExtractor(),newDummyExtractor());
33-
$this->propertyInfo =newPropertyInfoExtractor($extractors,$extractors,$extractors,$extractors);
34+
$this->propertyInfo =newPropertyInfoExtractor($extractors,$extractors,$extractors,$extractors,$extractors);
3435
}
3536

3637
publicfunctiontestInstanceOf()
@@ -39,6 +40,7 @@ public function testInstanceOf()
3940
$this->assertInstanceOf('Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface',$this->propertyInfo);
4041
$this->assertInstanceOf('Symfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface',$this->propertyInfo);
4142
$this->assertInstanceOf('Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface',$this->propertyInfo);
43+
$this->assertInstanceOf(PropertyInitializableExtractorInterface::class,$this->propertyInfo);
4244
}
4345

4446
publicfunctiontestGetShortDescription()
@@ -70,4 +72,9 @@ public function testGetProperties()
7072
{
7173
$this->assertEquals(array('a','b'),$this->propertyInfo->getProperties('Foo'));
7274
}
75+
76+
publicfunctiontestIsInitializable()
77+
{
78+
$this->assertTrue($this->propertyInfo->isInitializable('Foo','bar',array()));
79+
}
7380
}

‎src/Symfony/Component/PropertyInfo/Tests/DependencyInjection/PropertyInfoPassTest.php‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function testServicesAreOrderedAccordingToPriority($index, $tag)
2626
{
2727
$container =newContainerBuilder();
2828

29-
$definition =$container->register('property_info')->setArguments(array(null,null,null,null));
29+
$definition =$container->register('property_info')->setArguments(array(null,null,null,null,null));
3030
$container->register('n2')->addTag($tag,array('priority' =>100));
3131
$container->register('n1')->addTag($tag,array('priority' =>200));
3232
$container->register('n3')->addTag($tag);
@@ -49,14 +49,15 @@ public function provideTags()
4949
array(1,'property_info.type_extractor'),
5050
array(2,'property_info.description_extractor'),
5151
array(3,'property_info.access_extractor'),
52+
array(4,'property_info.initializable_extractor'),
5253
);
5354
}
5455

5556
publicfunctiontestReturningEmptyArrayWhenNoService()
5657
{
5758
$container =newContainerBuilder();
5859
$propertyInfoExtractorDefinition =$container->register('property_info')
59-
->setArguments(array(array(),array(),array(),array()));
60+
->setArguments(array(array(),array(),array(),array(),array()));
6061

6162
$propertyInfoPass =newPropertyInfoPass();
6263
$propertyInfoPass->process($container);
@@ -65,5 +66,6 @@ public function testReturningEmptyArrayWhenNoService()
6566
$this->assertEquals(newIteratorArgument(array()),$propertyInfoExtractorDefinition->getArgument(1));
6667
$this->assertEquals(newIteratorArgument(array()),$propertyInfoExtractorDefinition->getArgument(2));
6768
$this->assertEquals(newIteratorArgument(array()),$propertyInfoExtractorDefinition->getArgument(3));
69+
$this->assertEquals(newIteratorArgument(array()),$propertyInfoExtractorDefinition->getArgument(4));
6870
}
6971
}

‎src/Symfony/Component/PropertyInfo/Tests/Extractors/ReflectionExtractorTest.php‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
usePHPUnit\Framework\TestCase;
1515
useSymfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
1616
useSymfony\Component\PropertyInfo\Tests\Fixtures\AdderRemoverDummy;
17+
useSymfony\Component\PropertyInfo\Tests\Fixtures\Php71Dummy;
18+
useSymfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyChild3;
19+
useSymfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended;
20+
useSymfony\Component\PropertyInfo\Tests\Fixtures\Php71DummyExtended2;
1721
useSymfony\Component\PropertyInfo\Type;
1822

1923
/**
@@ -275,4 +279,24 @@ public function testSingularize()
275279
$this->assertTrue($this->extractor->isWritable(AdderRemoverDummy::class,'feet'));
276280
$this->assertEquals(array('analyses','feet'),$this->extractor->getProperties(AdderRemoverDummy::class));
277281
}
282+
283+
/**
284+
* @dataProvider getInitializableProperties
285+
*/
286+
publicfunctiontestIsInitializable(string$class,string$property,bool$expected)
287+
{
288+
$this->assertSame($expected,$this->extractor->isInitializable($class,$property));
289+
}
290+
291+
publicfunctiongetInitializableProperties():array
292+
{
293+
returnarray(
294+
array(Php71Dummy::class,'string',true),
295+
array(Php71Dummy::class,'intPrivate',true),
296+
array(Php71Dummy::class,'notExist',false),
297+
array(Php71DummyExtended::class,'intWithAccessor',true),
298+
array(Php71DummyExtended2::class,'intWithAccessor',true),
299+
array(Php71DummyExtended2::class,'intPrivate',false),
300+
);
301+
}
278302
}

‎src/Symfony/Component/PropertyInfo/Tests/Fixtures/DummyExtractor.php‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,15 @@
1313

1414
useSymfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
1515
useSymfony\Component\PropertyInfo\PropertyDescriptionExtractorInterface;
16+
useSymfony\Component\PropertyInfo\PropertyInitializableExtractorInterface;
1617
useSymfony\Component\PropertyInfo\PropertyListExtractorInterface;
1718
useSymfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
1819
useSymfony\Component\PropertyInfo\Type;
1920

2021
/**
2122
* @author Kévin Dunglas <dunglas@gmail.com>
2223
*/
23-
class DummyExtractorimplements PropertyListExtractorInterface, PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface
24+
class DummyExtractorimplements PropertyListExtractorInterface, PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface, PropertyInitializableExtractorInterface
2425
{
2526
/**
2627
* {@inheritdoc}
@@ -69,4 +70,12 @@ public function getProperties($class, array $context = array())
6970
{
7071
returnarray('a','b');
7172
}
73+
74+
/**
75+
* {@inheritdoc}
76+
*/
77+
publicfunctionisInitializable(string$class,string$property,array$context =array()): ?bool
78+
{
79+
returntrue;
80+
}
7281
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp