minor #23674 [DI] Inline trivial private servives (nicolas-grekas)

This PR was merged into the 4.0-dev branch.

Discussion
----------

[DI] Inline trivial private servives

| Q             | A
| ------------- | ---
| Branch?       | 4.0
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

There is no need to generate a method when the instantiation is just as verbose as calling that method.

Commits
-------

0caed939cd [DI] Inline trivial private servives
This commit is contained in:
Fabien Potencier 2017-07-28 08:47:29 +02:00
commit 03af7b93ad
9 changed files with 81 additions and 52 deletions

View File

@ -446,6 +446,50 @@ class PhpDumper extends Dumper
return true;
}
/**
* Checks if the definition is a trivial instance.
*
* @param Definition $definition
*
* @return bool
*/
private function isTrivialInstance(Definition $definition)
{
if ($definition->isPublic() || $definition->getMethodCalls() || $definition->getProperties() || $definition->getConfigurator()) {
return false;
}
if ($definition->isDeprecated() || $definition->isLazy() || $definition->getFactory() || 3 < count($definition->getArguments())) {
return false;
}
foreach ($definition->getArguments() as $arg) {
if (!$arg || ($arg instanceof Reference && 'service_container' !== (string) $arg)) {
continue;
}
if (is_array($arg) && 3 >= count($arg)) {
foreach ($arg as $k => $v) {
if ($this->dumpValue($k) !== $this->dumpValue($k, false)) {
return false;
}
if (!$v || ($v instanceof Reference && 'service_container' !== (string) $v)) {
continue;
}
if (!is_scalar($v) || $this->dumpValue($v) !== $this->dumpValue($v, false)) {
return false;
}
}
} elseif (!is_scalar($arg) || $this->dumpValue($arg) !== $this->dumpValue($arg, false)) {
return false;
}
}
if (false !== strpos($this->dumpLiteralClass($this->dumpValue($definition->getClass())), '$')) {
return false;
}
return true;
}
/**
* Adds method calls to a service definition.
*
@ -675,7 +719,7 @@ EOF;
foreach ($definitions as $id => $definition) {
if ($definition->isPublic()) {
$publicServices .= $this->addService($id, $definition);
} else {
} elseif (!$this->isTrivialInstance($definition)) {
$privateServices .= $this->addService($id, $definition);
}
}
@ -1504,10 +1548,18 @@ EOF;
}
if ($this->container->hasDefinition($id)) {
$code = sprintf('$this->%s()', $this->generateMethodName($id));
$definition = $this->container->getDefinition($id);
if ($this->container->getDefinition($id)->isShared()) {
$code = sprintf('($this->%s[\'%s\'] ?? %s)', $this->container->getDefinition($id)->isPublic() ? 'services' : 'privates', $id, $code);
if ($definition->isPublic() || !$this->isTrivialInstance($definition)) {
$code = sprintf('$this->%s()', $this->generateMethodName($id));
} else {
$code = substr($this->addNewInstance($definition, '', '', $id), 8, -2);
if ($definition->isShared()) {
$code = sprintf('($this->privates[\'%s\'] = %s)', $id, $code);
}
}
if ($definition->isShared()) {
$code = sprintf('($this->%s[\'%s\'] ?? %s)', $definition->isPublic() ? 'services' : 'privates', $id, $code);
}
} elseif (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) {
$code = sprintf('$this->get(\'%s\', ContainerInterface::NULL_ON_INVALID_REFERENCE)', $id);

View File

@ -125,6 +125,7 @@ $container
$container
->register('factory_simple', 'SimpleFactoryClass')
->addArgument('foo')
->setDeprecated(true)
->setPublic(false)
;
$container

View File

@ -231,7 +231,7 @@ class ProjectServiceContainer extends Container
*/
protected function getFactoryServiceSimpleService()
{
return $this->services['factory_service_simple'] = (new \SimpleFactoryClass('foo'))->getInstance();
return $this->services['factory_service_simple'] = ($this->privates['factory_simple'] ?? $this->getFactorySimpleService())->getInstance();
}
/**
@ -372,6 +372,20 @@ class ProjectServiceContainer extends Container
return $this->services['service_from_static_method'] = \Bar\FooClass::getInstance();
}
/**
* Gets the private 'factory_simple' shared service.
*
* @return \SimpleFactoryClass
*
* @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.
*/
private function getFactorySimpleService()
{
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
return $this->privates['factory_simple'] = new \SimpleFactoryClass('foo');
}
/**
* {@inheritdoc}
*/

View File

@ -74,7 +74,7 @@ class ProjectServiceContainer extends Container
*/
protected function getBarServiceService()
{
return $this->services['bar_service'] = new \stdClass(($this->privates['baz_service'] ?? $this->getBazServiceService()));
return $this->services['bar_service'] = new \stdClass(($this->privates['baz_service'] ?? ($this->privates['baz_service'] = new \stdClass())));
}
/**
@ -87,7 +87,7 @@ class ProjectServiceContainer extends Container
return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\ServiceLocator(array('bar' => function () {
return ($this->services['bar_service'] ?? $this->getBarServiceService());
}, 'baz' => function (): \stdClass {
return ($this->privates['baz_service'] ?? $this->getBazServiceService());
return ($this->privates['baz_service'] ?? ($this->privates['baz_service'] = new \stdClass()));
}, 'nil' => function () {
return NULL;
}));
@ -169,14 +169,4 @@ class ProjectServiceContainer extends Container
return $instance;
}
/**
* Gets the private 'baz_service' shared service.
*
* @return \stdClass
*/
private function getBazServiceService()
{
return $this->privates['baz_service'] = new \stdClass();
}
}

View File

@ -68,7 +68,7 @@ class ProjectServiceContainer extends Container
*/
protected function getBarServiceService()
{
return $this->services['bar_service'] = new \stdClass(($this->privates['baz_service'] ?? $this->getBazServiceService()));
return $this->services['bar_service'] = new \stdClass(($this->privates['baz_service'] ?? ($this->privates['baz_service'] = new \stdClass())));
}
/**
@ -78,16 +78,6 @@ class ProjectServiceContainer extends Container
*/
protected function getFooServiceService()
{
return $this->services['foo_service'] = new \stdClass(($this->privates['baz_service'] ?? $this->getBazServiceService()));
}
/**
* Gets the private 'baz_service' shared service.
*
* @return \stdClass
*/
private function getBazServiceService()
{
return $this->privates['baz_service'] = new \stdClass();
return $this->services['foo_service'] = new \stdClass(($this->privates['baz_service'] ?? ($this->privates['baz_service'] = new \stdClass())));
}
}

View File

@ -67,16 +67,6 @@ class ProjectServiceContainer extends Container
*/
protected function getPublicFooService()
{
return $this->services['public_foo'] = new \stdClass(($this->privates['private_foo'] ?? $this->getPrivateFooService()));
}
/**
* Gets the private 'private_foo' shared service.
*
* @return \stdClass
*/
private function getPrivateFooService()
{
return $this->privates['private_foo'] = new \stdClass();
return $this->services['public_foo'] = new \stdClass(($this->privates['private_foo'] ?? ($this->privates['private_foo'] = new \stdClass())));
}
}

View File

@ -79,23 +79,13 @@ class ProjectServiceContainer extends Container
protected function getFooServiceService()
{
return $this->services['foo_service'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber(new \Symfony\Component\DependencyInjection\ServiceLocator(array('Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\CustomDefinition' => function (): \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition {
return ($this->privates['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] ?? $this->getAutowired_Symfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService());
return ($this->privates['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] ?? ($this->privates['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition()));
}, 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\TestServiceSubscriber' => function (): \Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber {
return ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] ?? $this->getSymfony_Component_DependencyInjection_Tests_Fixtures_TestServiceSubscriberService());
}, 'bar' => function (): \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition {
return ($this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\TestServiceSubscriber'] ?? $this->getSymfony_Component_DependencyInjection_Tests_Fixtures_TestServiceSubscriberService());
}, 'baz' => function (): \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition {
return ($this->privates['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] ?? $this->getAutowired_Symfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService());
return ($this->privates['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] ?? ($this->privates['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition()));
})));
}
/**
* Gets the private 'autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition' shared autowired service.
*
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition
*/
private function getAutowired_Symfony_Component_DependencyInjection_Tests_Fixtures_CustomDefinitionService()
{
return $this->privates['autowired.Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\CustomDefinition();
}
}

View File

@ -112,6 +112,7 @@
</service>
<service id="factory_simple" class="SimpleFactoryClass" public="false">
<argument>foo</argument>
<deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.</deprecated>
</service>
<service id="factory_service_simple" class="Bar">
<factory service="factory_simple" method="getInstance"/>

View File

@ -105,6 +105,7 @@ services:
factory: [Bar\FooClass, getInstance]
factory_simple:
class: SimpleFactoryClass
deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.
public: false
arguments: ['foo']
factory_service_simple: