From 6a65742b6aeea04a448aa85d40a552e88ce54a32 Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Thu, 7 May 2020 18:18:17 +0200 Subject: [PATCH] [DependencyInjection] Always preload services classes tagged with container.preload --- .../DependencyInjection/Dumper/PhpDumper.php | 24 +- .../Tests/Dumper/PhpDumperTest.php | 4 +- .../Tests/Fixtures/config/services9.php | 9 + .../Tests/Fixtures/containers/container9.php | 9 + .../Tests/Fixtures/graphviz/services9.dot | 2 + .../Tests/Fixtures/php/services9_as_files.txt | 232 +++++++++++------- .../Tests/Fixtures/php/services9_compiled.php | 22 ++ .../php/services9_inlined_factories.txt | 25 +- .../php/services_errored_definition.php | 22 ++ .../Tests/Fixtures/xml/services9.xml | 7 + .../Tests/Fixtures/yaml/services9.yml | 11 + 11 files changed, 260 insertions(+), 107 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php index 5c8bb9c9d34ca..015771dac4dbe 100644 --- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php +++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php @@ -584,7 +584,7 @@ private function addServiceInclude(string $cId, Definition $definition): string $lineage = []; foreach ($this->inlinedDefinitions as $def) { if (!$def->isDeprecated()) { - foreach ($this->getClasses($def, $cId) as $class) { + foreach ($this->getClasses($def) as $class) { $this->collectLineage($class, $lineage); } } @@ -596,7 +596,7 @@ private function addServiceInclude(string $cId, Definition $definition): string && $this->container->has($id) && $this->isTrivialInstance($def = $this->container->findDefinition($id)) ) { - foreach ($this->getClasses($def, $cId) as $class) { + foreach ($this->getClasses($def) as $class) { $this->collectLineage($class, $lineage); } } @@ -851,9 +851,9 @@ protected function {$methodName}($lazyInitialization) if ($definition->isDeprecated()) { $deprecation = $definition->getDeprecation($id); $code .= sprintf(" trigger_deprecation(%s, %s, %s);\n\n", $this->export($deprecation['package']), $this->export($deprecation['version']), $this->export($deprecation['message'])); - } elseif (!$definition->hasTag($this->preloadTags[1])) { + } elseif ($definition->hasTag($this->preloadTags[0]) || !$definition->hasTag($this->preloadTags[1])) { foreach ($this->inlinedDefinitions as $def) { - foreach ($this->getClasses($def, $id) as $class) { + foreach ($this->getClasses($def) as $class) { $this->preload[$class] = $class; } } @@ -1017,10 +1017,10 @@ private function addServices(array &$services = null): string foreach ($definitions as $id => $definition) { if (!$definition->isSynthetic()) { $services[$id] = $this->addService($id, $definition); - } elseif (!$definition->hasTag($this->preloadTags[1])) { + } elseif ($definition->hasTag($this->preloadTags[0]) || !$definition->hasTag($this->preloadTags[1])) { $services[$id] = null; - foreach ($this->getClasses($definition, $id) as $class) { + foreach ($this->getClasses($definition) as $class) { $this->preload[$class] = $class; } } @@ -1046,7 +1046,7 @@ private function generateServiceFiles(array $services): iterable ksort($definitions); foreach ($definitions as $id => $definition) { if ((list($file, $code) = $services[$id]) && null !== $file && ($definition->isPublic() || !$this->isTrivialInstance($definition) || isset($this->locatedIds[$id]))) { - yield $file => [$code, !$definition->hasTag($this->preloadTags[1]) && !$definition->isDeprecated() && !$definition->hasErrors()]; + yield $file => [$code, ($definition->hasTag($this->preloadTags[0]) || !$definition->hasTag($this->preloadTags[1])) && !$definition->isDeprecated() && !$definition->hasErrors()]; } } } @@ -1399,7 +1399,7 @@ private function addInlineRequires(): string $inlinedDefinitions = $this->getDefinitionsFromArguments([$definition]); foreach ($inlinedDefinitions as $def) { - foreach ($this->getClasses($def, $id) as $class) { + foreach ($this->getClasses($def) as $class) { $this->collectLineage($class, $lineage); } } @@ -2130,17 +2130,15 @@ private function getAutoloadFile(): ?string return null; } - private function getClasses(Definition $definition, string $id): array + private function getClasses(Definition $definition): array { $classes = []; while ($definition instanceof Definition) { foreach ($definition->getTag($this->preloadTags[0]) as $tag) { - if (!isset($tag['class'])) { - throw new InvalidArgumentException(sprintf('Missing attribute "class" on tag "%s" for service "%s".', $this->preloadTags[0], $id)); + if (isset($tag['class'])) { + $classes[] = trim($tag['class'], '\\'); } - - $classes[] = trim($tag['class'], '\\'); } $classes[] = trim($definition->getClass(), '\\'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php index 93000ab82eb5a..aa105d5c27c8f 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php @@ -236,11 +236,11 @@ public function testDumpAsFiles() ->addError('No-no-no-no'); $container->compile(); $dumper = new PhpDumper($container); - $dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'hot_path_tag' => 'hot', 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false]), true); + $dump = print_r($dumper->dump(['as_files' => true, 'file' => __DIR__, 'hot_path_tag' => 'hot', 'inline_factories_parameter' => false, 'inline_class_loader_parameter' => false, 'build_time' => 1588866825]), true); if ('\\' === \DIRECTORY_SEPARATOR) { $dump = str_replace('\\\\Fixtures\\\\includes\\\\foo.php', '/Fixtures/includes/foo.php', $dump); } - $this->assertStringMatchesFormatFile(self::$fixturesPath.'/php/services9_as_files.txt', $dump); + $this->assertStringEqualsFile(self::$fixturesPath.'/php/services9_as_files.txt', $dump); } public function testDumpAsFilesWithFactoriesInlined() diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php index 2d5a1cdc93bac..d09ca435ba161 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/services9.php @@ -137,6 +137,15 @@ ->tag('container.preload', ['class' => 'Some\Sidekick2']) ->public(); + $s->set('no_preload', 'TestNoPreload') + ->tag('container.no_preload') + ->public(); + + $s->set('preload_no_preload', 'TestPreloadNoPreload') + ->tag('container.preload') + ->tag('container.no_preload') + ->public(); + $s->alias('alias_for_foo', 'foo')->private()->public(); $s->alias('alias_for_alias', ref('alias_for_foo')); }; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php index a1d71b9d94fba..b1936c52d4482 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/containers/container9.php @@ -193,4 +193,13 @@ ->addTag('container.preload', ['class' => 'Some\Sidekick1']) ->addTag('container.preload', ['class' => 'Some\Sidekick2']); +$container->register('no_preload', 'TestNoPreload') + ->addTag('container.no_preload') + ->setPublic(true); + +$container->register('preload_no_preload', 'TestPreloadNoPreload') + ->addTag('container.preload') + ->addTag('container.no_preload') + ->setPublic(true); + return $container; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot index 994506f25a4b4..8456a807e8ee4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/graphviz/services9.dot @@ -37,6 +37,8 @@ digraph sc { node_runtime_error [label="runtime_error\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_errored_definition [label="errored_definition\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_preload_sidekick [label="preload_sidekick\nstdClass\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_no_preload [label="no_preload\nTestNoPreload\n", shape=record, fillcolor="#eeeeee", style="filled"]; + node_preload_no_preload [label="preload_no_preload\nTestPreloadNoPreload\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"]; node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"]; node_foobaz [label="foobaz\n\n", shape=record, fillcolor="#ff9999", style="filled"]; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt index d7ab192e9aa2b..ca6e492827086 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt @@ -1,8 +1,8 @@ Array ( - [Container%s/removed-ids.php] => true, @@ -19,9 +19,9 @@ return [ 'tagged_iterator_foo' => true, ]; - [Container%s/getBAR2Service.php] => services['no_preload'] = new \TestNoPreload(); + } +} + + [ContainerB4qnkfR/getNonSharedFooService.php] => services['preload_no_preload'] = new \TestPreloadNoPreload(); + } +} + + [ContainerB4qnkfR/getPreloadSidekickService.php] => 'getLazyContextIgnoreInvalidRefService', 'method_call1' => 'getMethodCall1Service', 'new_factory_service' => 'getNewFactoryServiceService', + 'no_preload' => 'getNoPreloadService', 'non_shared_foo' => 'getNonSharedFooService', + 'preload_no_preload' => 'getPreloadNoPreloadService', 'preload_sidekick' => 'getPreloadSidekickService', 'runtime_error' => 'getRuntimeErrorService', 'service_from_static_method' => 'getServiceFromStaticMethodService', @@ -891,32 +939,33 @@ class ProjectServiceContainer extends Container use Symfony\Component\DependencyInjection\Dumper\Preloader; -require dirname(__DIR__, %d).'%svendor/autoload.php'; -require __DIR__.'/Container%s/ProjectServiceContainer.php'; -require __DIR__.'/Container%s/getThrowingOneService.php'; -require __DIR__.'/Container%s/getTaggedIteratorService.php'; -require __DIR__.'/Container%s/getServiceFromStaticMethodService.php'; -require __DIR__.'/Container%s/getRuntimeErrorService.php'; -require __DIR__.'/Container%s/getPreloadSidekickService.php'; -require __DIR__.'/Container%s/getNonSharedFooService.php'; -require __DIR__.'/Container%s/getNewFactoryServiceService.php'; -require __DIR__.'/Container%s/getMethodCall1Service.php'; -require __DIR__.'/Container%s/getLazyContextIgnoreInvalidRefService.php'; -require __DIR__.'/Container%s/getLazyContextService.php'; -require __DIR__.'/Container%s/getFooWithInlineService.php'; -require __DIR__.'/Container%s/getFooBarService.php'; -require __DIR__.'/Container%s/getFoo_BazService.php'; -require __DIR__.'/Container%s/getFooService.php'; -require __DIR__.'/Container%s/getFactoryServiceSimpleService.php'; -require __DIR__.'/Container%s/getFactoryServiceService.php'; -require __DIR__.'/Container%s/getDecoratorServiceWithNameService.php'; -require __DIR__.'/Container%s/getDecoratorServiceService.php'; -require __DIR__.'/Container%s/getConfiguredServiceSimpleService.php'; -require __DIR__.'/Container%s/getConfiguredServiceService.php'; -require __DIR__.'/Container%s/getBazService.php'; -require __DIR__.'/Container%s/getBar23Service.php'; -require __DIR__.'/Container%s/getBAR22Service.php'; -require __DIR__.'/Container%s/getBAR2Service.php'; +require dirname(__DIR__, 5).'/vendor/autoload.php'; +require __DIR__.'/ContainerB4qnkfR/ProjectServiceContainer.php'; +require __DIR__.'/ContainerB4qnkfR/getThrowingOneService.php'; +require __DIR__.'/ContainerB4qnkfR/getTaggedIteratorService.php'; +require __DIR__.'/ContainerB4qnkfR/getServiceFromStaticMethodService.php'; +require __DIR__.'/ContainerB4qnkfR/getRuntimeErrorService.php'; +require __DIR__.'/ContainerB4qnkfR/getPreloadSidekickService.php'; +require __DIR__.'/ContainerB4qnkfR/getPreloadNoPreloadService.php'; +require __DIR__.'/ContainerB4qnkfR/getNonSharedFooService.php'; +require __DIR__.'/ContainerB4qnkfR/getNewFactoryServiceService.php'; +require __DIR__.'/ContainerB4qnkfR/getMethodCall1Service.php'; +require __DIR__.'/ContainerB4qnkfR/getLazyContextIgnoreInvalidRefService.php'; +require __DIR__.'/ContainerB4qnkfR/getLazyContextService.php'; +require __DIR__.'/ContainerB4qnkfR/getFooWithInlineService.php'; +require __DIR__.'/ContainerB4qnkfR/getFooBarService.php'; +require __DIR__.'/ContainerB4qnkfR/getFoo_BazService.php'; +require __DIR__.'/ContainerB4qnkfR/getFooService.php'; +require __DIR__.'/ContainerB4qnkfR/getFactoryServiceSimpleService.php'; +require __DIR__.'/ContainerB4qnkfR/getFactoryServiceService.php'; +require __DIR__.'/ContainerB4qnkfR/getDecoratorServiceWithNameService.php'; +require __DIR__.'/ContainerB4qnkfR/getDecoratorServiceService.php'; +require __DIR__.'/ContainerB4qnkfR/getConfiguredServiceSimpleService.php'; +require __DIR__.'/ContainerB4qnkfR/getConfiguredServiceService.php'; +require __DIR__.'/ContainerB4qnkfR/getBazService.php'; +require __DIR__.'/ContainerB4qnkfR/getBar23Service.php'; +require __DIR__.'/ContainerB4qnkfR/getBAR22Service.php'; +require __DIR__.'/ContainerB4qnkfR/getBAR2Service.php'; $classes = []; $classes[] = 'Bar\FooClass'; @@ -928,6 +977,7 @@ $classes[] = 'Foo'; $classes[] = 'LazyContext'; $classes[] = 'FooBarBaz'; $classes[] = 'FactoryClass'; +$classes[] = 'TestPreloadNoPreload'; $classes[] = 'Some\Sidekick1'; $classes[] = 'Some\Sidekick2'; $classes[] = 'Request'; @@ -939,22 +989,22 @@ Preloader::preload($classes); // This file has been auto-generated by the Symfony Dependency Injection Component for internal use. -if (\class_exists(\Container%s\ProjectServiceContainer::class, false)) { +if (\class_exists(\ContainerB4qnkfR\ProjectServiceContainer::class, false)) { // no-op -} elseif (!include __DIR__.'/Container%s/ProjectServiceContainer.php') { - touch(__DIR__.'/Container%s.legacy'); +} elseif (!include __DIR__.'/ContainerB4qnkfR/ProjectServiceContainer.php') { + touch(__DIR__.'/ContainerB4qnkfR.legacy'); return; } if (!\class_exists(ProjectServiceContainer::class, false)) { - \class_alias(\Container%s\ProjectServiceContainer::class, ProjectServiceContainer::class, false); + \class_alias(\ContainerB4qnkfR\ProjectServiceContainer::class, ProjectServiceContainer::class, false); } -return new \Container%s\ProjectServiceContainer([ - 'container.build_hash' => '%s', - 'container.build_id' => '%s', - 'container.build_time' => %d, -], __DIR__.\DIRECTORY_SEPARATOR.'Container%s'); +return new \ContainerB4qnkfR\ProjectServiceContainer([ + 'container.build_hash' => 'B4qnkfR', + 'container.build_id' => '8094687a', + 'container.build_time' => 1588866825, +], __DIR__.\DIRECTORY_SEPARATOR.'ContainerB4qnkfR'); ) diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php index 277da470b544c..842e5d7ccfe03 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php @@ -45,6 +45,8 @@ public function __construct() 'lazy_context_ignore_invalid_ref' => 'getLazyContextIgnoreInvalidRefService', 'method_call1' => 'getMethodCall1Service', 'new_factory_service' => 'getNewFactoryServiceService', + 'no_preload' => 'getNoPreloadService', + 'preload_no_preload' => 'getPreloadNoPreloadService', 'preload_sidekick' => 'getPreloadSidekickService', 'runtime_error' => 'getRuntimeErrorService', 'service_from_static_method' => 'getServiceFromStaticMethodService', @@ -360,6 +362,26 @@ protected function getNewFactoryServiceService() return $instance; } + /** + * Gets the public 'no_preload' shared service. + * + * @return \TestNoPreload + */ + protected function getNoPreloadService() + { + return $this->services['no_preload'] = new \TestNoPreload(); + } + + /** + * Gets the public 'preload_no_preload' shared service. + * + * @return \TestPreloadNoPreload + */ + protected function getPreloadNoPreloadService() + { + return $this->services['preload_no_preload'] = new \TestPreloadNoPreload(); + } + /** * Gets the public 'preload_sidekick' shared service. * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_inlined_factories.txt b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_inlined_factories.txt index 34f1689ce6077..e7a8aa99c0d31 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_inlined_factories.txt +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_inlined_factories.txt @@ -74,7 +74,9 @@ class ProjectServiceContainer extends Container 'lazy_context_ignore_invalid_ref' => 'getLazyContextIgnoreInvalidRefService', 'method_call1' => 'getMethodCall1Service', 'new_factory_service' => 'getNewFactoryServiceService', + 'no_preload' => 'getNoPreloadService', 'non_shared_foo' => 'getNonSharedFooService', + 'preload_no_preload' => 'getPreloadNoPreloadService', 'preload_sidekick' => 'getPreloadSidekickService', 'runtime_error' => 'getRuntimeErrorService', 'service_from_static_method' => 'getServiceFromStaticMethodService', @@ -389,6 +391,16 @@ class ProjectServiceContainer extends Container return $instance; } + /** + * Gets the public 'no_preload' shared service. + * + * @return \TestNoPreload + */ + protected function getNoPreloadService() + { + return $this->services['no_preload'] = new \TestNoPreload(); + } + /** * Gets the public 'non_shared_foo' service. * @@ -401,6 +413,16 @@ class ProjectServiceContainer extends Container return new \Bar\FooClass(); } + /** + * Gets the public 'preload_no_preload' shared service. + * + * @return \TestPreloadNoPreload + */ + protected function getPreloadNoPreloadService() + { + return $this->services['preload_no_preload'] = new \TestPreloadNoPreload(); + } + /** * Gets the public 'preload_sidekick' shared service. * @@ -559,6 +581,7 @@ $classes[] = 'Foo'; $classes[] = 'LazyContext'; $classes[] = 'FooBarBaz'; $classes[] = 'FactoryClass'; +$classes[] = 'TestPreloadNoPreload'; $classes[] = 'Some\Sidekick1'; $classes[] = 'Some\Sidekick2'; $classes[] = 'Request'; @@ -584,7 +607,7 @@ if (!\class_exists(ProjectServiceContainer::class, false)) { return new \Container%s\ProjectServiceContainer([ 'container.build_hash' => '%s', - 'container.build_id' => '%s', + 'container.build_id' => 'd4a1510a', 'container.build_time' => 1563381341, ], __DIR__.\DIRECTORY_SEPARATOR.'Container%s'); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php index 9f2bb02158a92..8d0ad7295056d 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php @@ -45,6 +45,8 @@ public function __construct() 'lazy_context_ignore_invalid_ref' => 'getLazyContextIgnoreInvalidRefService', 'method_call1' => 'getMethodCall1Service', 'new_factory_service' => 'getNewFactoryServiceService', + 'no_preload' => 'getNoPreloadService', + 'preload_no_preload' => 'getPreloadNoPreloadService', 'preload_sidekick' => 'getPreloadSidekickService', 'runtime_error' => 'getRuntimeErrorService', 'service_from_static_method' => 'getServiceFromStaticMethodService', @@ -360,6 +362,26 @@ protected function getNewFactoryServiceService() return $instance; } + /** + * Gets the public 'no_preload' shared service. + * + * @return \TestNoPreload + */ + protected function getNoPreloadService() + { + return $this->services['no_preload'] = new \TestNoPreload(); + } + + /** + * Gets the public 'preload_no_preload' shared service. + * + * @return \TestPreloadNoPreload + */ + protected function getPreloadNoPreloadService() + { + return $this->services['preload_no_preload'] = new \TestPreloadNoPreload(); + } + /** * Gets the public 'preload_sidekick' shared service. * diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml index cc7a2e116e5bd..55a97ec08c684 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml @@ -153,6 +153,13 @@ + + + + + + + The "%alias_id%" autowiring alias is deprecated. Define it explicitly in your app if you want to keep using it. diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml index 43694e0fa9281..3695fc2f2a781 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml @@ -198,3 +198,14 @@ services: - container.preload: { class: 'Some\Sidekick1' } - container.preload: { class: 'Some\Sidekick2' } public: true + no_preload: + class: TestNoPreload + tags: + - container.no_preload + public: true + preload_no_preload: + class: TestPreloadNoPreload + tags: + - container.preload + - container.no_preload + public: true