[DI] : Fix bad generation of proxy class when use overriden getter on class with constructor
- [X] Add test fail - [X] Fix bug - [X] Run test pass
This commit is contained in:
parent
46daa359ea
commit
2440b0f05d
@ -525,9 +525,9 @@ class PhpDumper extends Dumper
|
||||
}
|
||||
if (!$r->isFinal()) {
|
||||
if (0 < $r->getNumberOfParameters()) {
|
||||
$getters = implode('($container'.$this->salt.', ', explode('(', $this->generateSignature($r), 2));
|
||||
$getters = implode('__construct($container'.$this->salt.', ', explode('(', $this->generateSignature($r), 2));
|
||||
} else {
|
||||
$getters = '($container'.$this->salt.')';
|
||||
$getters = '__construct($container'.$this->salt.')';
|
||||
}
|
||||
$getters = sprintf("\n public function %s\n {\n \$this->container%3\$s = \$container%3\$s;\n parent::%s;\n }\n", $getters, $this->generateCall($r), $this->salt);
|
||||
} else {
|
||||
|
@ -344,6 +344,27 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame('baz', $r->invoke($baz));
|
||||
}
|
||||
|
||||
public function testDumpOverridenGettersWithConstructor()
|
||||
{
|
||||
$container = include self::$fixturesPath.'/containers/container_dump_overriden_getters_with_constructor.php';
|
||||
$container->compile();
|
||||
$container->getDefinition('foo')
|
||||
->setOverriddenGetter('getInvalid', array(new Reference('bar', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE)));
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
$dump = $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Overriden_Getters_With_Constructor'));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_dump_overriden_getters_with_constructor.php', $dump);
|
||||
$resources = array_map('strval', $container->getResources());
|
||||
$this->assertContains(realpath(self::$fixturesPath.'/containers/container_dump_overriden_getters_with_constructor.php'), $resources);
|
||||
|
||||
$baz = $container->get('baz');
|
||||
$r = new \ReflectionMethod($baz, 'getBaz');
|
||||
$r->setAccessible(true);
|
||||
|
||||
$this->assertTrue($r->isProtected());
|
||||
$this->assertSame('baz', $r->invoke($baz));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideBadOverridenGetters
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
|
||||
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container34;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
if (!class_exists(Foo::class, false)) {
|
||||
abstract class Foo
|
||||
{
|
||||
protected $bar;
|
||||
|
||||
public function __construct($bar = 'bar')
|
||||
{
|
||||
$this->bar = $bar;
|
||||
}
|
||||
|
||||
abstract public function getPublic();
|
||||
abstract protected function getProtected();
|
||||
|
||||
public function getSelf()
|
||||
{
|
||||
return 123;
|
||||
}
|
||||
|
||||
public function getInvalid()
|
||||
{
|
||||
return 456;
|
||||
}
|
||||
|
||||
public function getGetProtected()
|
||||
{
|
||||
return $this->getProtected();
|
||||
}
|
||||
}
|
||||
|
||||
class Baz
|
||||
{
|
||||
final public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
protected function getBaz()
|
||||
{
|
||||
return 234;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$container = new ContainerBuilder();
|
||||
|
||||
$container
|
||||
->register('foo', Foo::class)
|
||||
->setOverriddenGetter('getPublic', 'public')
|
||||
->setOverriddenGetter('getProtected', 'protected')
|
||||
->setOverriddenGetter('getSelf', new Reference('foo'))
|
||||
;
|
||||
|
||||
$container
|
||||
->register('baz', Baz::class)
|
||||
->setOverriddenGetter('getBaz', 'baz')
|
||||
;
|
||||
|
||||
return $container;
|
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
||||
|
||||
/**
|
||||
* Symfony_DI_PhpDumper_Test_Overriden_Getters_With_Constructor.
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Dependency Injection Component.
|
||||
*
|
||||
* @final since Symfony 3.3
|
||||
*/
|
||||
class Symfony_DI_PhpDumper_Test_Overriden_Getters_With_Constructor extends Container
|
||||
{
|
||||
private $parameters;
|
||||
private $targetDirs = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->services = array();
|
||||
$this->methodMap = array(
|
||||
'baz' => 'getBazService',
|
||||
'foo' => 'getFooService',
|
||||
);
|
||||
|
||||
$this->aliases = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped frozen container.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isFrozen()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'baz' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Baz A Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Baz instance
|
||||
*/
|
||||
protected function getBazService()
|
||||
{
|
||||
return $this->services['baz'] = $this->instantiateProxy(SymfonyProxy_a9f1de23b86d1fe2b860654ab2128883::class, array(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the 'foo' service.
|
||||
*
|
||||
* This service is shared.
|
||||
* This method always returns the same instance of the service.
|
||||
*
|
||||
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Foo A Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Foo instance
|
||||
*/
|
||||
protected function getFooService()
|
||||
{
|
||||
return $this->services['foo'] = new SymfonyProxy_cbcc1d1a7dc6a97b54a307ad6a012531($this);
|
||||
}
|
||||
|
||||
private function instantiateProxy($class, $args, $useConstructor)
|
||||
{
|
||||
static $reflectionCache;
|
||||
|
||||
if (null === $r = &$reflectionCache[$class]) {
|
||||
$r[0] = new \ReflectionClass($class);
|
||||
$r[1] = $r[0]->getProperty('containerg3aCmsigw5jaB68sqMSEQQ');
|
||||
$r[1]->setAccessible(true);
|
||||
$r[2] = $r[0]->getConstructor();
|
||||
}
|
||||
$service = $useConstructor ? $r[0]->newInstanceWithoutConstructor() : $r[0]->newInstanceArgs($args);
|
||||
$r[1]->setValue($service, $this);
|
||||
if ($r[2] && $useConstructor) {
|
||||
$r[2]->invokeArgs($service, $args);
|
||||
}
|
||||
|
||||
return $service;
|
||||
}
|
||||
}
|
||||
|
||||
class SymfonyProxy_a9f1de23b86d1fe2b860654ab2128883 extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Baz implements \Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface
|
||||
{
|
||||
private $containerg3aCmsigw5jaB68sqMSEQQ;
|
||||
private $gettersg3aCmsigw5jaB68sqMSEQQ;
|
||||
|
||||
protected function getBaz()
|
||||
{
|
||||
return 'baz';
|
||||
}
|
||||
}
|
||||
|
||||
class SymfonyProxy_cbcc1d1a7dc6a97b54a307ad6a012531 extends \Symfony\Component\DependencyInjection\Tests\Fixtures\Container34\Foo implements \Symfony\Component\DependencyInjection\LazyProxy\GetterProxyInterface
|
||||
{
|
||||
private $containerg3aCmsigw5jaB68sqMSEQQ;
|
||||
private $gettersg3aCmsigw5jaB68sqMSEQQ;
|
||||
|
||||
public function __construct($containerg3aCmsigw5jaB68sqMSEQQ, $bar = 'bar')
|
||||
{
|
||||
$this->containerg3aCmsigw5jaB68sqMSEQQ = $containerg3aCmsigw5jaB68sqMSEQQ;
|
||||
parent::__construct($bar);
|
||||
}
|
||||
|
||||
public function getPublic()
|
||||
{
|
||||
return 'public';
|
||||
}
|
||||
|
||||
protected function getProtected()
|
||||
{
|
||||
return 'protected';
|
||||
}
|
||||
|
||||
public function getSelf()
|
||||
{
|
||||
if (null === $g = &$this->gettersg3aCmsigw5jaB68sqMSEQQ[__FUNCTION__]) {
|
||||
$g = \Closure::bind(function () { return ${($_ = isset($this->services['foo']) ? $this->services['foo'] : $this->get('foo')) && false ?: '_'}; }, $this->containerg3aCmsigw5jaB68sqMSEQQ, $this->containerg3aCmsigw5jaB68sqMSEQQ);
|
||||
}
|
||||
|
||||
return $g();
|
||||
}
|
||||
|
||||
public function getInvalid()
|
||||
{
|
||||
if (null === $g = &$this->gettersg3aCmsigw5jaB68sqMSEQQ[__FUNCTION__]) {
|
||||
$g = \Closure::bind(function () { return array(0 => $this->get('bar', ContainerInterface::NULL_ON_INVALID_REFERENCE)); }, $this->containerg3aCmsigw5jaB68sqMSEQQ, $this->containerg3aCmsigw5jaB68sqMSEQQ);
|
||||
}
|
||||
|
||||
if ($this->containerg3aCmsigw5jaB68sqMSEQQ->has('bar')) {
|
||||
return $g();
|
||||
}
|
||||
|
||||
return parent::getInvalid();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user