feature #21244 [DI] Remove synthetic services from methodMap + generated methods (nicolas-grekas)

This PR was merged into the 3.3-dev branch.

Discussion
----------

[DI] Remove synthetic services from methodMap + generated methods

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

For synthetic services, the generated methods are just dead code to fill opcache ;)
And having them in "methodMap" prevents using the property for checking if a service comes from a (non-synthetic) definition or not.
This prepares some changes that we'd like to do in 4.0, see #19668.

Commits
-------

c1e1e999f3 [DI] Remove synthetic services from methodMap + generated methods
This commit is contained in:
Fabien Potencier 2017-01-15 08:42:11 -08:00
commit f7679f74ae
5 changed files with 31 additions and 58 deletions

View File

@ -205,10 +205,13 @@ class Container implements ResettableContainerInterface
public function has($id)
{
for ($i = 2;;) {
if ('service_container' === $id
|| isset($this->aliases[$id])
|| isset($this->services[$id])
) {
if ('service_container' === $id) {
return true;
}
if (isset($this->aliases[$id])) {
$id = $this->aliases[$id];
}
if (isset($this->services[$id])) {
return true;
}

View File

@ -591,15 +591,16 @@ class PhpDumper extends Dumper
*/
private function addService($id, Definition $definition)
{
if ($definition->isSynthetic()) {
return '';
}
$this->definitionVariables = new \SplObjectStorage();
$this->referenceVariables = array();
$this->variableCount = 0;
$return = array();
if ($definition->isSynthetic()) {
$return[] = '@throws RuntimeException always since this service is expected to be injected dynamically';
} elseif ($class = $definition->getClass()) {
if ($class = $definition->getClass()) {
$class = $this->container->resolveEnvPlaceholders($class);
$return[] = sprintf('@return %s A %s instance', 0 === strpos($class, '%') ? 'object' : '\\'.ltrim($class, '\\'), ltrim($class, '\\'));
} elseif ($definition->getFactory()) {
@ -680,26 +681,22 @@ EOF;
$code .= $isProxyCandidate ? $this->getProxyDumper()->getProxyFactoryCode($definition, $id, $methodName) : '';
if ($definition->isSynthetic()) {
$code .= sprintf(" throw new RuntimeException('You have requested a synthetic service (\"%s\"). The DIC does not know how to construct this service.');\n }\n", $id);
} else {
if ($definition->isDeprecated()) {
$code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id)));
}
$code .=
$this->addServiceInclude($id, $definition).
$this->addServiceLocalTempVariables($id, $definition).
$this->addServiceInlinedDefinitions($id, $definition).
$this->addServiceInstance($id, $definition).
$this->addServiceInlinedDefinitionsSetup($id, $definition).
$this->addServiceProperties($id, $definition).
$this->addServiceMethodCalls($id, $definition).
$this->addServiceConfigurator($id, $definition).
$this->addServiceReturn($id, $definition)
;
if ($definition->isDeprecated()) {
$code .= sprintf(" @trigger_error(%s, E_USER_DEPRECATED);\n\n", $this->export($definition->getDeprecationMessage($id)));
}
$code .=
$this->addServiceInclude($id, $definition).
$this->addServiceLocalTempVariables($id, $definition).
$this->addServiceInlinedDefinitions($id, $definition).
$this->addServiceInstance($id, $definition).
$this->addServiceInlinedDefinitionsSetup($id, $definition).
$this->addServiceProperties($id, $definition).
$this->addServiceMethodCalls($id, $definition).
$this->addServiceConfigurator($id, $definition).
$this->addServiceReturn($id, $definition)
;
$this->definitionVariables = null;
$this->referenceVariables = null;
@ -952,7 +949,8 @@ EOF;
*/
private function addMethodMap()
{
if (!$definitions = $this->container->getDefinitions()) {
$definitions = $this->container->getDefinitions();
if (!$definitions || !$definitions = array_filter($definitions, function ($def) { return !$def->isSynthetic(); })) {
return '';
}

View File

@ -286,15 +286,15 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage You have requested a synthetic service ("request"). The DIC does not know how to construct this service.
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
* @expectedExceptionMessage You have requested a non-existent service "request".
*/
public function testGetSyntheticServiceAlwaysThrows()
public function testGetSyntheticServiceThrows()
{
require_once __DIR__.'/Fixtures/php/services9.php';
$container = new \ProjectServiceContainer();
$container->get('request', ContainerInterface::NULL_ON_INVALID_REFERENCE);
$container->get('request');
}
public function testHas()

View File

@ -52,7 +52,6 @@ class ProjectServiceContainer extends Container
'method_call1' => 'getMethodCall1Service',
'new_factory' => 'getNewFactoryService',
'new_factory_service' => 'getNewFactoryServiceService',
'request' => 'getRequestService',
'service_from_static_method' => 'getServiceFromStaticMethodService',
);
$this->privates = array(
@ -386,19 +385,6 @@ class ProjectServiceContainer extends Container
return $instance;
}
/**
* Gets the 'request' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @throws RuntimeException always since this service is expected to be injected dynamically
*/
protected function getRequestService()
{
throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.');
}
/**
* Gets the 'service_from_static_method' service.
*

View File

@ -48,7 +48,6 @@ class ProjectServiceContainer extends Container
'lazy_context_ignore_invalid_ref' => 'getLazyContextIgnoreInvalidRefService',
'method_call1' => 'getMethodCall1Service',
'new_factory_service' => 'getNewFactoryServiceService',
'request' => 'getRequestService',
'service_from_static_method' => 'getServiceFromStaticMethodService',
);
$this->aliases = array(
@ -379,19 +378,6 @@ class ProjectServiceContainer extends Container
return $instance;
}
/**
* Gets the 'request' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
* @throws RuntimeException always since this service is expected to be injected dynamically
*/
protected function getRequestService()
{
throw new RuntimeException('You have requested a synthetic service ("request"). The DIC does not know how to construct this service.');
}
/**
* Gets the 'service_from_static_method' service.
*