8000 Add support of self and parent · symfony/symfony@8eb1972 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8eb1972

Browse files
committed
Add support of self and parent
1 parent a635a06 commit 8eb1972

File tree

3 files changed

+76
-13
lines changed

3 files changed

+76
-13
lines changed

src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ private function updateDefinition(ContainerBuilder $container, $id, Definition $
4848
}
4949

5050
if (is_string($factory) && function_exists($factory)) {
51-
$reflection = new \ReflectionFunction($factory);
52-
$returnType = $reflection->getReturnType();
51+
$reflectionFunction = new \ReflectionFunction($factory);
5352
} else {
5453
if ($factory[0] instanceof Reference) {
5554
$this->updateDefinition(
@@ -64,15 +63,24 @@ private function updateDefinition(ContainerBuilder $container, $id, Definition $
6463
}
6564

6665
try {
67-
$reflectionClass = new \ReflectionMethod($class, $factory[1]);
66+
$reflectionFunction = new \ReflectionMethod($class, $factory[1]);
6867
} catch (\ReflectionException $e) {
6968
return;
7069
}
71-
$returnType = $reflectionClass->getReturnType();
7270
}
7371

72+
$returnType = $reflectionFunction->getReturnType();
7473
if (null !== $returnType && !$returnType->isBuiltin()) {
75-
$definition->setClass((string) $returnType);
74+
$returnType = (string) $returnType;
75+
if (isset($class)) {
76+
if ('self' === $returnType) {
77+
$returnType = $class;
78+
} elseif ('parent' === $returnType) {
79+
$returnType = get_parent_class($class) ?: null;
80+
}
81+
}
82+
83+
$definition->setClass($returnType);
7684
}
7785
}
7886
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/FactoryReturnTypePassTest.php

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\DependencyInjection\ContainerBuilder;
1616
use Symfony\Component\DependencyInjection\Reference;
1717
use Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummy;
18+
use Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryParent;
1819

1920
/**
2021
* @author Guilhem N. <egetick@gmail.com>
@@ -26,33 +27,74 @@ public function testProcess()
2627
$container = new ContainerBuilder();
2728

2829
$factory = $container->register('factory');
29-
$factory->setFactory(array(FactoryDummy::class, 'createSelf'));
30+
$factory->setFactory(array(FactoryDummy::class, 'createFactory'));
3031

3132
$foo = $container->register('foo');
3233
$foo->setFactory(array(new Reference('factory'), 'create'));
3334

35+
$bar = $container->register('bar', __CLASS__);
36+
$bar->setFactory(array(new Reference('factory'), 'create'));
37+
3438
$pass = new FactoryReturnTypePass();
3539
$pass->process($container);
3640

37-
if (PHP_VERSION_ID >= 70000) {
41+
if (method_exists(\ReflectionMethod::class, 'getReturnType')) {
3842
$this->assertEquals(FactoryDummy::class, $factory->getClass());
3943
$this->assertEquals(\stdClass::class, $foo->getClass());
4044
} else {
4145
$this->assertNull($factory->getClass());
4246
$this->assertNull($foo->getClass());
4347
}
48+
$this->assertEquals(__CLASS__, $bar->getClass());
4449
}
4550

46-
public function testBuiltinReturnType()
51+
/**
52+
* @dataProvider returnTypesProvider
53+
*/
54+
public function testReturnTypes($method, $returnType, $hhvmSupport = true)
4755
{
56+
if (!$hhvmSupport && defined('HHVM_VERSION')) {
57+
$this->markTestSkipped('Special types not supported by hhvm.');
58+
}
59+
4860
$container = new ContainerBuilder();
4961

50-
$service = $container->register('builtin');
51-
$service->setFactory(array(FactoryDummy::class, 'createBuiltin'));
62+
$service = $container->register('service');
63+
$service->setFactory(array(FactoryDummy::class, $method));
64+
65+
$pass = new FactoryReturnTypePass();
66+
$pass->process($container);
67+
68+
if (method_exists(\ReflectionMethod::class, 'getReturnType')) {
69+
$this->assertEquals($returnType, $service->getClass());
70+
} else {
71+
$this->assertNull($service->getClass());
72+
}
73+
}
74+
75+
public function returnTypesProvider()
76+
{
77+
return array(
78+
array('createBuiltin', null, false),
79+
array('createParent', FactoryParent::class),
80+
array('createSelf', FactoryDummy::class),
81+
);
82+
}
83+
84+
public function testCircularReference()
85+
{
86+
$container = new ContainerBuilder();
87+
88+
$factory = $container->register('factory');
89+
$factory->setFactory(array(new Reference('factory2'), 'createSelf'));
90+
91+
$factory2 = $container->register('factory2');
92+
$factory2->setFactory(array(new Reference('factory'), 'create'));
5293

5394
$pass = new FactoryReturnTypePass();
5495
$pass->process($container);
5596

56-
$this->assertNull($service->getClass());
97+
$this->assertNull($factory->getClass());
98+
$this->assertNull($factory2->getClass());
5799
}
58100
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/FactoryDummy.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,30 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
1313

14-
class FactoryDummy
14+
class FactoryDummy extends FactoryParent
1515
{
16-
public static function createSelf(): FactoryDummy
16+
public static function createFactory(): FactoryDummy
1717
{
1818
}
1919

2020
public function create(): \stdClass
2121
{
2222
}
2323

24+
// Not supported by hhvm
2425
public function createBuiltin(): int
2526
{
2627
}
28+
29+
public static function createSelf(): self
30+
{
31+
}
32+
33+
public static function createParent(): parent
34+
{
35+
}
36+
}
37+
38+
class FactoryParent
39+
{
2740
}

0 commit comments

Comments
 (0)
0