diff --git a/src/Symfony/Component/DependencyInjection/ChildDefinition.php b/src/Symfony/Component/DependencyInjection/ChildDefinition.php
index b75124f61977f..d202170e373b2 100644
--- a/src/Symfony/Component/DependencyInjection/ChildDefinition.php
+++ b/src/Symfony/Component/DependencyInjection/ChildDefinition.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\DependencyInjection;
+use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
@@ -134,6 +135,22 @@ public function replaceArgument($index, $value)
return $this;
}
+
+ /**
+ * @internal
+ */
+ public function setAutoconfigured($autoconfigured)
+ {
+ throw new BadMethodCallException('A ChildDefinition cannot be autoconfigured.');
+ }
+
+ /**
+ * @internal
+ */
+ public function setInstanceofConditionals(array $instanceof)
+ {
+ throw new BadMethodCallException('A ChildDefinition cannot have instanceof conditionals set on it.');
+ }
}
class_alias(ChildDefinition::class, DefinitionDecorator::class);
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
index 0be05dea23bcb..f4f8cd5c151c7 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
@@ -101,7 +101,6 @@ private function doResolveDefinition(ChildDefinition $definition)
$def->setPublic($parentDef->isPublic());
$def->setLazy($parentDef->isLazy());
$def->setAutowired($parentDef->isAutowired());
- $def->setAutoconfigured($parentDef->isAutoconfigured());
$def->setChanges($parentDef->getChanges());
// overwrite with values specified in the decorator
@@ -130,9 +129,6 @@ private function doResolveDefinition(ChildDefinition $definition)
if (isset($changes['autowired'])) {
$def->setAutowired($definition->isAutowired());
}
- if (isset($changes['autoconfigured'])) {
- $def->setAutoconfigured($definition->isAutoconfigured());
- }
if (isset($changes['shared'])) {
$def->setShared($definition->isShared());
}
@@ -174,6 +170,9 @@ private function doResolveDefinition(ChildDefinition $definition)
// these attributes are always taken from the child
$def->setAbstract($definition->isAbstract());
$def->setTags($definition->getTags());
+ // autoconfigure is never taken from parent (on purpose)
+ // and it's not legal on an instanceof
+ $def->setAutoconfigured($definition->isAutoconfigured());
return $def;
}
diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
index 555e8eb36fe3e..6ec07672567d6 100644
--- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
+++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php
@@ -15,6 +15,7 @@
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
+use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
/**
* Applies instanceof conditionals to definitions.
@@ -28,6 +29,15 @@ class ResolveInstanceofConditionalsPass implements CompilerPassInterface
*/
public function process(ContainerBuilder $container)
{
+ foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) {
+ if ($definition->getArguments()) {
+ throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface));
+ }
+ if ($definition->getMethodCalls()) {
+ throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines method calls but these are not supported and should be removed.', $interface));
+ }
+ }
+
foreach ($container->getDefinitions() as $id => $definition) {
if ($definition instanceof ChildDefinition) {
// don't apply "instanceof" to children: it will be applied to their parent
@@ -40,8 +50,8 @@ public function process(ContainerBuilder $container)
private function processDefinition(ContainerBuilder $container, $id, Definition $definition)
{
$instanceofConditionals = $definition->getInstanceofConditionals();
- $automaticInstanceofConditionals = $definition->isAutoconfigured() ? $container->getAutomaticInstanceofDefinitions() : array();
- if (!$instanceofConditionals && !$automaticInstanceofConditionals) {
+ $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : array();
+ if (!$instanceofConditionals && !$autoconfiguredInstanceof) {
return $definition;
}
@@ -49,7 +59,7 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
return $definition;
}
- $conditionals = $this->mergeConditionals($automaticInstanceofConditionals, $instanceofConditionals, $container);
+ $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container);
$definition->setInstanceofConditionals(array());
$parent = $shared = null;
@@ -113,10 +123,10 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
return $definition;
}
- private function mergeConditionals(array $automaticInstanceofConditionals, array $instanceofConditionals, ContainerBuilder $container)
+ private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container)
{
// make each value an array of ChildDefinition
- $conditionals = array_map(function ($childDef) { return array($childDef); }, $automaticInstanceofConditionals);
+ $conditionals = array_map(function ($childDef) { return array($childDef); }, $autoconfiguredInstanceof);
foreach ($instanceofConditionals as $interface => $instanceofDef) {
// make sure the interface/class exists (but don't validate automaticInstanceofConditionals)
@@ -124,7 +134,7 @@ private function mergeConditionals(array $automaticInstanceofConditionals, array
throw new RuntimeException(sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface));
}
- if (!isset($automaticInstanceofConditionals[$interface])) {
+ if (!isset($autoconfiguredInstanceof[$interface])) {
$conditionals[$interface] = array();
}
diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
index 910427b210788..929b8983cacc4 100644
--- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php
@@ -118,7 +118,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
*/
private $vendors;
- private $automaticInstanceofDefinitions = array();
+ private $autoconfiguredInstanceof = array();
public function __construct(ParameterBagInterface $parameterBag = null)
{
@@ -641,12 +641,12 @@ public function merge(ContainerBuilder $container)
}
}
- foreach ($container->getAutomaticInstanceofDefinitions() as $interface => $childDefinition) {
- if (isset($this->automaticInstanceofDefinitions[$interface])) {
+ foreach ($container->getAutoconfiguredInstanceof() as $interface => $childDefinition) {
+ if (isset($this->autoconfiguredInstanceof[$interface])) {
throw new InvalidArgumentException(sprintf('"%s" has already been autoconfigured and merge() does not support merging autoconfiguration for the same class/interface.', $interface));
}
- $this->automaticInstanceofDefinitions[$interface] = $childDefinition;
+ $this->autoconfiguredInstanceof[$interface] = $childDefinition;
}
}
@@ -1272,15 +1272,16 @@ public function getExpressionLanguageProviders()
* Returns a ChildDefinition that will be used for autoconfiguring the interface/class.
*
* @param string $interface The class or interface to match
+ *
* @return ChildDefinition
*/
public function registerForAutoconfiguration($interface)
{
- if (!isset($this->automaticInstanceofDefinitions[$interface])) {
- $this->automaticInstanceofDefinitions[$interface] = new ChildDefinition('');
+ if (!isset($this->autoconfiguredInstanceof[$interface])) {
+ $this->autoconfiguredInstanceof[$interface] = new ChildDefinition('');
}
- return $this->automaticInstanceofDefinitions[$interface];
+ return $this->autoconfiguredInstanceof[$interface];
}
/**
@@ -1288,9 +1289,9 @@ public function registerForAutoconfiguration($interface)
*
* @return ChildDefinition[]
*/
- public function getAutomaticInstanceofDefinitions()
+ public function getAutoconfiguredInstanceof()
{
- return $this->automaticInstanceofDefinitions;
+ return $this->autoconfiguredInstanceof;
}
/**
diff --git a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php
index e183fdad42167..4e3c37d87eb72 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/FileLoader.php
@@ -79,7 +79,7 @@ protected function setDefinition($id, Definition $definition)
}
$this->instanceof[$id] = $definition;
} else {
- $this->container->setDefinition($id, $definition->setInstanceofConditionals($this->instanceof));
+ $this->container->setDefinition($id, $definition instanceof ChildDefinition ? $definition : $definition->setInstanceofConditionals($this->instanceof));
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 9f730472d72e1..b9a0f004e73e1 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -215,6 +215,14 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults =
if ($this->isLoadingInstanceof) {
$definition = new ChildDefinition('');
} elseif ($parent = $service->getAttribute('parent')) {
+ if (!empty($this->instanceof)) {
+ throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "instanceof" configuration is defined as using both is not supported. Try moving your child definitions to a different file.', $service->getAttribute('id')));
+ }
+
+ if (!empty($defaults)) {
+ throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "defaults" configuration is defined as using both is not supported. Try moving your child definitions to a different file.', $service->getAttribute('id')));
+ }
+
$definition = new ChildDefinition($parent);
if ($value = $service->getAttribute('inherit-tags')) {
@@ -255,7 +263,11 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults =
}
if ($value = $service->getAttribute('autoconfigure')) {
- $definition->setAutoconfigured(XmlUtils::phpize($value));
+ if (!$definition instanceof ChildDefinition) {
+ $definition->setAutoconfigured(XmlUtils::phpize($value));
+ } elseif ($value = XmlUtils::phpize($value)) {
+ throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try setting autoconfigure="false" for the service.', $service->getAttribute('id')));
+ }
}
if ($files = $this->getChildren($service, 'file')) {
diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
index e7703aabf89a9..7ee19e7f6c50c 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
@@ -88,7 +88,6 @@ class YamlFileLoader extends FileLoader
'calls' => 'calls',
'tags' => 'tags',
'autowire' => 'autowire',
- 'autoconfigure' => 'autoconfigure',
);
private static $defaultsKeywords = array(
@@ -357,6 +356,14 @@ private function parseDefinition($id, $service, $file, array $defaults)
if ($this->isLoadingInstanceof) {
$definition = new ChildDefinition('');
} elseif (isset($service['parent'])) {
+ if (!empty($this->instanceof)) {
+ throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "_instanceof" configuration is defined as using both is not supported. Try moving your child definitions to a different file.', $id));
+ }
+
+ if (!empty($defaults)) {
+ throw new InvalidArgumentException(sprintf('The service "%s" cannot use the "parent" option in the same file where "_defaults" configuration is defined as using both is not supported. Try moving your child definitions to a different file.', $id));
+ }
+
$definition = new ChildDefinition($service['parent']);
$inheritTag = isset($service['inherit_tags']) ? $service['inherit_tags'] : (isset($defaults['inherit_tags']) ? $defaults['inherit_tags'] : null);
@@ -518,7 +525,11 @@ private function parseDefinition($id, $service, $file, array $defaults)
}
if (isset($service['autoconfigure'])) {
- $definition->setAutoconfigured($service['autoconfigure']);
+ if (!$definition instanceof ChildDefinition) {
+ $definition->setAutoconfigured($service['autoconfigure']);
+ } elseif ($service['autoconfigure']) {
+ throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try setting "autoconfigure: false" for the service.', $id));
+ }
}
if (array_key_exists('resource', $service)) {
diff --git a/src/Symfony/Component/DependencyInjection/Tests/ChildDefinitionTest.php b/src/Symfony/Component/DependencyInjection/Tests/ChildDefinitionTest.php
index 0890f53cdbbbe..a367a8b2c4d03 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/ChildDefinitionTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/ChildDefinitionTest.php
@@ -132,4 +132,22 @@ public function testDefinitionDecoratorAliasExistsForBackwardsCompatibility()
{
$this->assertInstanceOf(ChildDefinition::class, new DefinitionDecorator('foo'));
}
+
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\BadMethodCallException
+ */
+ public function testCannotCallSetAutoconfigured()
+ {
+ $def = new ChildDefinition('foo');
+ $def->setAutoconfigured(true);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\BadMethodCallException
+ */
+ public function testCannotCallSetInstanceofConditionals()
+ {
+ $def = new ChildDefinition('foo');
+ $def->setInstanceofConditionals(array('Foo' => new ChildDefinition('')));
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php
index 9d75c0b962186..a1856dfe84828 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/IntegrationTest.php
@@ -117,64 +117,86 @@ public function testProcessInlinesWhenThereAreMultipleReferencesButFromTheSameDe
$this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.');
}
- public function testInstanceofDefaultsAndParentDefinitionResolution()
+ /**
+ * @dataProvider getYamlCompileTests
+ */
+ public function testYamlContainerCompiles($directory, $actualServiceId, $expectedServiceId, ContainerBuilder $mainContainer = null)
{
- $container = new ContainerBuilder();
+ // allow a container to be passed in, which might have autoconfigure settings
+ $container = $mainContainer ? $mainContainer : new ContainerBuilder();
$container->setResourceTracking(false);
+ $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Fixtures/yaml/integration/'.$directory));
+ $loader->load('main.yml');
+ $container->compile();
+ $actualService = $container->getDefinition($actualServiceId);
- // loading YAML with an expressive test-case in that file
- $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Fixtures/yaml'));
- $loader->load('services_defaults_instanceof_parent.yml');
+ // create a fresh ContainerBuilder, to avoid autoconfigure stuff
+ $container = new ContainerBuilder();
+ $container->setResourceTracking(false);
+ $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Fixtures/yaml/integration/'.$directory));
+ $loader->load('expected.yml');
$container->compile();
+ $expectedService = $container->getDefinition($expectedServiceId);
+
+ // reset changes, we don't care if these differ
+ $actualService->setChanges(array());
+ $expectedService->setChanges(array());
+
+ $this->assertEquals($expectedService, $actualService);
+ }
+
+ public function getYamlCompileTests()
+ {
+ $container = new ContainerBuilder();
+ $container->registerForAutoconfiguration(IntegrationTestStub::class);
+ yield array(
+ 'autoconfigure_child_not_applied',
+ 'child_service',
+ 'child_service_expected',
+ $container,
+ );
+
+ $container = new ContainerBuilder();
+ $container->registerForAutoconfiguration(IntegrationTestStub::class);
+ yield array(
+ 'autoconfigure_parent_child',
+ 'child_service',
+ 'child_service_expected',
+ $container,
+ );
+
+ $container = new ContainerBuilder();
+ $container->registerForAutoconfiguration(IntegrationTestStub::class)
+ ->addTag('from_autoconfigure');
+ yield array(
+ 'autoconfigure_parent_child_tags',
+ 'child_service',
+ 'child_service_expected',
+ $container,
+ );
+
+ yield array(
+ 'child_parent',
+ 'child_service',
+ 'child_service_expected',
+ );
- // instanceof overrides defaults
- $simpleService = $container->getDefinition('service_simple');
- $this->assertFalse($simpleService->isAutowired());
- $this->assertFalse($simpleService->isAutoconfigured());
- $this->assertFalse($simpleService->isShared());
-
- // all tags are kept
- $this->assertEquals(
- array(
- 'foo_tag' => array(array('tag_option' => 'from_service'), array('tag_option' => 'from_instanceof')),
- 'bar_tag' => array(array()),
- ),
- $simpleService->getTags()
+ yield array(
+ 'defaults_instanceof_importance',
+ 'main_service',
+ 'main_service_expected',
);
- // calls are all kept, but service-level calls are last
- $this->assertEquals(
- array(
- // from instanceof
- array('setSunshine', array('bright')),
- // from service
- array('enableSummer', array(true)),
- array('setSunshine', array('warm')),
- ),
- $simpleService->getMethodCalls()
+ yield array(
+ 'defaults_parent_child',
+ 'child_service',
+ 'child_service_expected',
);
- // service override instanceof
- $overrideService = $container->getDefinition('service_override_instanceof');
- $this->assertTrue($overrideService->isAutowired());
- $this->assertTrue($overrideService->isAutoconfigured());
-
- // children definitions get no instanceof
- $childDef = $container->getDefinition('child_service');
- $this->assertEmpty($childDef->getTags());
-
- $childDef2 = $container->getDefinition('child_service_with_parent_instanceof');
- // taken from instanceof applied to parent
- $this->assertFalse($childDef2->isAutowired());
- // override the instanceof
- $this->assertTrue($childDef2->isShared());
- // tags inherit like normal
- $this->assertEquals(
- array(
- 'foo_tag' => array(array('tag_option' => 'from_child_def'), array('tag_option' => 'from_parent_def'), array('tag_option' => 'from_instanceof')),
- 'bar_tag' => array(array()),
- ),
- $childDef2->getTags()
+ yield array(
+ 'instanceof_parent_child',
+ 'child_service',
+ 'child_service_expected',
);
}
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
index a2dd9b130d536..9c64c502f659a 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveDefinitionTemplatesPassTest.php
@@ -381,23 +381,6 @@ public function testProcessSetsArguments()
$this->assertSame(array(2, 1, 'foo' => 3), $def->getArguments());
}
- public function testSetAutoconfiguredOnServiceHasParent()
- {
- $container = new ContainerBuilder();
-
- $container->register('parent', 'stdClass')
- ->setAutoconfigured(true)
- ;
-
- $container->setDefinition('child1', new ChildDefinition('parent'))
- ->setAutoconfigured(false)
- ;
-
- $this->process($container);
-
- $this->assertFalse($container->getDefinition('child1')->isAutoconfigured());
- }
-
public function testSetAutoconfiguredOnServiceIsParent()
{
$container = new ContainerBuilder();
@@ -410,7 +393,7 @@ public function testSetAutoconfiguredOnServiceIsParent()
$this->process($container);
- $this->assertTrue($container->getDefinition('child1')->isAutoconfigured());
+ $this->assertFalse($container->getDefinition('child1')->isAutoconfigured());
}
protected function process(ContainerBuilder $container)
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php
index 03ef2d40b8250..6467ac7ed4d71 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php
@@ -56,9 +56,6 @@ public function testProcessInheritance()
));
$def = (new ChildDefinition('parent'))->setClass(self::class);
- $def->setInstanceofConditionals(array(
- parent::class => (new ChildDefinition(''))->addMethodCall('foo', array('baz')),
- ));
$container->setDefinition('child', $def);
(new ResolveInstanceofConditionalsPass())->process($container);
@@ -108,7 +105,7 @@ public function testProcessHandlesMultipleInheritance()
$this->assertTrue($def->isShared());
}
- public function testProcessUsesAutomaticInstanceofDefinitions()
+ public function testProcessUsesAutoconfiguredInstanceof()
{
$container = new ContainerBuilder();
$def = $container->register('normal_service', self::class);
@@ -119,24 +116,24 @@ public function testProcessUsesAutomaticInstanceofDefinitions()
));
$def->setAutoconfigured(true);
$container->registerForAutoconfiguration(parent::class)
- ->addTag('automatic_instanceof_tag')
+ ->addTag('autoconfigured_tag')
->setAutowired(true)
- ->setFactory('automatically_set_factory');
+ ->setFactory('autoconfigured_factory');
(new ResolveInstanceofConditionalsPass())->process($container);
(new ResolveTagsInheritancePass())->process($container);
(new ResolveDefinitionTemplatesPass())->process($container);
$def = $container->getDefinition('normal_service');
- // autowired thanks to the automatic instanceof
+ // autowired thanks to the autoconfigured instanceof
$this->assertTrue($def->isAutowired());
// factory from the specific instanceof overrides global one
$this->assertEquals('locally_set_factory', $def->getFactory());
// tags are merged, the locally set one is first
- $this->assertSame(array('local_instanceof_tag' => array(array()), 'automatic_instanceof_tag' => array(array())), $def->getTags());
+ $this->assertSame(array('local_instanceof_tag' => array(array()), 'autoconfigured_tag' => array(array())), $def->getTags());
}
- public function testProcessDoesNotUseAutomaticInstanceofDefinitionsIfNotEnabled()
+ public function testProcessDoesNotUseAutoconfiguredInstanceofIfNotEnabled()
{
$container = new ContainerBuilder();
$def = $container->register('normal_service', self::class);
@@ -151,7 +148,6 @@ public function testProcessDoesNotUseAutomaticInstanceofDefinitionsIfNotEnabled(
(new ResolveDefinitionTemplatesPass())->process($container);
$def = $container->getDefinition('normal_service');
- // no automatic_tag, it was not enabled on the Definition
$this->assertFalse($def->isAutowired());
}
@@ -171,7 +167,7 @@ public function testBadInterfaceThrowsException()
(new ResolveInstanceofConditionalsPass())->process($container);
}
- public function testBadInterfaceForAutomaticInstanceofIsOkException()
+ public function testBadInterfaceForAutomaticInstanceofIsOk()
{
$container = new ContainerBuilder();
$container->register('normal_service', self::class)
@@ -182,4 +178,30 @@ public function testBadInterfaceForAutomaticInstanceofIsOkException()
(new ResolveInstanceofConditionalsPass())->process($container);
$this->assertTrue($container->hasDefinition('normal_service'));
}
+
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Autoconfigured instanceof for type "PHPUnit\Framework\TestCase" defines method calls but these are not supported and should be removed.
+ */
+ public function testProcessThrowsExceptionForAutoconfiguredCalls()
+ {
+ $container = new ContainerBuilder();
+ $container->registerForAutoconfiguration(parent::class)
+ ->addMethodCall('setFoo');
+
+ (new ResolveInstanceofConditionalsPass())->process($container);
+ }
+
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
+ * @expectedExceptionMessage Autoconfigured instanceof for type "PHPUnit\Framework\TestCase" defines arguments but these are not supported and should be removed.
+ */
+ public function testProcessThrowsExceptionForArguments()
+ {
+ $container = new ContainerBuilder();
+ $container->registerForAutoconfiguration(parent::class)
+ ->addArgument('bar');
+
+ (new ResolveInstanceofConditionalsPass())->process($container);
+ }
}
diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
index 552898f73d555..05c549bcce2fe 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
@@ -573,7 +573,7 @@ public function testMerge()
$childDefA = $container->registerForAutoconfiguration('AInterface');
$childDefB = $config->registerForAutoconfiguration('BInterface');
$container->merge($config);
- $this->assertSame(array('AInterface' => $childDefA, 'BInterface' => $childDefB), $container->getAutomaticInstanceofDefinitions());
+ $this->assertSame(array('AInterface' => $childDefA, 'BInterface' => $childDefB), $container->getAutoconfiguredInstanceof());
}
/**
@@ -1123,7 +1123,7 @@ public function testRegisterForAutoconfiguration()
$container = new ContainerBuilder();
$childDefA = $container->registerForAutoconfiguration('AInterface');
$childDefB = $container->registerForAutoconfiguration('BInterface');
- $this->assertSame(array('AInterface' => $childDefA, 'BInterface' => $childDefB), $container->getAutomaticInstanceofDefinitions());
+ $this->assertSame(array('AInterface' => $childDefA, 'BInterface' => $childDefB), $container->getAutoconfiguredInstanceof());
// when called multiple times, the same instance is returned
$this->assertSame($childDefA, $container->registerForAutoconfiguration('AInterface'));
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services29.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services29.xml
index 4ab511ed92dbf..81f1c1a4409a1 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services29.xml
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services29.xml
@@ -8,11 +8,5 @@
-
-
-
-
-
-
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_autoconfigure_with_parent.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_autoconfigure_with_parent.xml
new file mode 100644
index 0000000000000..103045d38fcb3
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_autoconfigure_with_parent.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_defaults_with_parent.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_defaults_with_parent.xml
new file mode 100644
index 0000000000000..875ed6d51f996
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_defaults_with_parent.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_instanceof_with_parent.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_instanceof_with_parent.xml
new file mode 100644
index 0000000000000..67ce6917249bd
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services_instanceof_with_parent.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/_child.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/_child.yml
new file mode 100644
index 0000000000000..89d8b914491eb
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/_child.yml
@@ -0,0 +1,4 @@
+services:
+ child_service:
+ class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
+ parent: parent_service
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/expected.yml
new file mode 100644
index 0000000000000..ca08caad673f7
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/expected.yml
@@ -0,0 +1,10 @@
+services:
+ child_service_expected:
+ class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
+ # the parent has autoconfigure true, but that does not cascade to the child
+ autoconfigure: false
+ # an autoconfigured "instanceof" is setup for IntegrationTestStub
+ # but its calls are NOT added, because the class was only
+ # set on the parent, not the child
+ #calls:
+ # - [enableSummer, [true]]
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/main.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/main.yml
new file mode 100644
index 0000000000000..02533bf0f5739
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_child_not_applied/main.yml
@@ -0,0 +1,7 @@
+imports:
+ - { resource: _child.yml }
+
+services:
+ parent_service:
+ autoconfigure: true
+ abstract: true
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/_child.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/_child.yml
new file mode 100644
index 0000000000000..5319c2045f93a
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/_child.yml
@@ -0,0 +1,3 @@
+services:
+ child_service:
+ parent: parent_service
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/expected.yml
new file mode 100644
index 0000000000000..c1dca0763cc90
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/expected.yml
@@ -0,0 +1,5 @@
+services:
+ child_service_expected:
+ class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
+ # autoconfigure is set on the parent, but not on the child
+ autoconfigure: false
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/main.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/main.yml
new file mode 100644
index 0000000000000..ab9877d16b9e7
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child/main.yml
@@ -0,0 +1,7 @@
+imports:
+ - { resource: _child.yml }
+
+services:
+ parent_service:
+ class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
+ autoconfigure: true
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/_child.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/_child.yml
new file mode 100644
index 0000000000000..5319c2045f93a
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/_child.yml
@@ -0,0 +1,3 @@
+services:
+ child_service:
+ parent: parent_service
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/expected.yml
new file mode 100644
index 0000000000000..02cf0037e215d
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/expected.yml
@@ -0,0 +1,6 @@
+services:
+ child_service_expected:
+ class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
+ # from an autoconfigured "instanceof" applied to parent class
+ # but NOT inherited down to child
+ # tags: [from_autoconfigure]
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/main.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/main.yml
new file mode 100644
index 0000000000000..ab9877d16b9e7
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/autoconfigure_parent_child_tags/main.yml
@@ -0,0 +1,7 @@
+imports:
+ - { resource: _child.yml }
+
+services:
+ parent_service:
+ class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
+ autoconfigure: true
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/child_parent/expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/child_parent/expected.yml
new file mode 100644
index 0000000000000..54cd91c2022a8
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/child_parent/expected.yml
@@ -0,0 +1,9 @@
+services:
+ # child_service in the end should be identical to this
+ child_service_expected:
+ class: stdClass
+ autowire: false
+ public: true
+ lazy: true
+ # ONLY the child tag, the parent tag does not inherit
+ tags: [from_child]
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/child_parent/main.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/child_parent/main.yml
new file mode 100644
index 0000000000000..edaa3a3b43993
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/child_parent/main.yml
@@ -0,0 +1,13 @@
+services:
+ parent_service:
+ abstract: true
+ lazy: true
+ autowire: false
+ public: false
+ tags: [from_parent]
+
+ child_service:
+ class: stdClass
+ parent: parent_service
+ public: true
+ tags: [from_child]
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/expected.yml
new file mode 100644
index 0000000000000..4edeffa7c3053
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/expected.yml
@@ -0,0 +1,27 @@
+services:
+ # main_service should look like this in the end
+ main_service_expected:
+ class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
+ # _instanceof overrides _defaults
+ autowire: false
+ # inherited from _defaults
+ autoconfigure: true
+ # from _instanceof
+ shared: false
+ # service definition overrides _instanceof
+ public: true
+
+ tags:
+ - { name: foo_tag, tag_option: from_service }
+ # these 2 are from instanceof
+ - { name: foo_tag, tag_option: from_instanceof }
+ - { name: bar_tag }
+ # the tag from defaults do NOT cascade (but see #22530)
+ # - { name: from_defaults }
+ # calls from instanceof are kept, but this comes later
+ calls:
+ # first call is from instanceof
+ - [setSunshine, [bright]]
+ #
+ - [enableSummer, [true]]
+ - [setSunshine, [warm]]
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/main.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/main.yml
new file mode 100644
index 0000000000000..406a351d1d3ef
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_instanceof_importance/main.yml
@@ -0,0 +1,30 @@
+services:
+ _defaults:
+ autowire: true
+ autoconfigure: true
+ public: true
+ tags: [from_defaults]
+
+ _instanceof:
+ Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStubParent:
+ autowire: false
+ shared: false
+ public: false
+ tags:
+ - { name: foo_tag, tag_option: from_instanceof }
+ calls:
+ - [setSunshine, [bright]]
+
+ Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub:
+ tags:
+ - { name: bar_tag }
+
+ main_service:
+ class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
+ public: true
+ tags:
+ - { name: foo_tag, tag_option: from_service }
+ # calls from instanceof are kept, but this comes later
+ calls:
+ - [enableSummer, [true]]
+ - [setSunshine, [warm]]
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_parent_child/_child.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_parent_child/_child.yml
new file mode 100644
index 0000000000000..86ef83c26dfca
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_parent_child/_child.yml
@@ -0,0 +1,4 @@
+services:
+ # loaded here to avoid defaults in other file
+ child_service:
+ parent: parent_service
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_parent_child/expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_parent_child/expected.yml
new file mode 100644
index 0000000000000..012672ff8b8fb
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_parent_child/expected.yml
@@ -0,0 +1,6 @@
+services:
+ child_service_expected:
+ class: stdClass
+ # _defaults is applied to the parent, but autoconfigure: true
+ # does not cascade to the child
+ autoconfigure: false
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_parent_child/main.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_parent_child/main.yml
new file mode 100644
index 0000000000000..8b90b4e985892
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/defaults_parent_child/main.yml
@@ -0,0 +1,9 @@
+imports:
+ - { resource: _child.yml }
+
+services:
+ _defaults:
+ autoconfigure: true
+
+ parent_service:
+ class: stdClass
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/instanceof_parent_child/_child.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/instanceof_parent_child/_child.yml
new file mode 100644
index 0000000000000..86ef83c26dfca
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/instanceof_parent_child/_child.yml
@@ -0,0 +1,4 @@
+services:
+ # loaded here to avoid defaults in other file
+ child_service:
+ parent: parent_service
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/instanceof_parent_child/expected.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/instanceof_parent_child/expected.yml
new file mode 100644
index 0000000000000..074ed01d03c4c
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/instanceof_parent_child/expected.yml
@@ -0,0 +1,7 @@
+services:
+ child_service_expected:
+ class: stdClass
+ # applied to _instanceof of parent
+ autowire: true
+ # from _instanceof, applies to parent, but does NOT inherit to here
+ # tags: [from_instanceof]
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/instanceof_parent_child/main.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/instanceof_parent_child/main.yml
new file mode 100644
index 0000000000000..44cf9b0045d40
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/integration/instanceof_parent_child/main.yml
@@ -0,0 +1,11 @@
+imports:
+ - { resource: _child.yml }
+
+services:
+ _instanceof:
+ stdClass:
+ autowire: true
+ tags: [from_instanceof]
+
+ parent_service:
+ class: stdClass
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services28.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services28.yml
index 99f72f1f94ac4..cacebf469cf2e 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services28.yml
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services28.yml
@@ -22,19 +22,6 @@ services:
autowire: false
tags: []
- no_defaults_child:
- parent: no_defaults
- autowire: ~
- tags:
- - name: bar
-
- with_defaults_child:
- parent: with_defaults
- public: true
- inherit_tags: true
- tags:
- - name: baz
-
with_defaults_aliased:
alias: with_defaults
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_autoconfigure_with_parent.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_autoconfigure_with_parent.yml
new file mode 100644
index 0000000000000..c6e3080192a7e
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_autoconfigure_with_parent.yml
@@ -0,0 +1,8 @@
+services:
+ parent_service:
+ class: stdClass
+
+ child_service:
+ class: stdClass
+ autoconfigure: true
+ parent: parent_service
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_instanceof_parent.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_instanceof_parent.yml
deleted file mode 100644
index 9e332a8405b0b..0000000000000
--- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_instanceof_parent.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-services:
- _defaults:
- autowire: true
- autoconfigure: true
-
- _instanceof:
- Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStubParent:
- # should override _defaults
- autowire: false
- autoconfigure: false
- shared: false
- tags:
- - { name: foo_tag, tag_option: from_instanceof }
- calls:
- - [setSunshine, [bright]]
-
- # a second instanceof that will be applied
- Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub:
- tags:
- - { name: bar_tag }
-
- service_simple:
- class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
- tags:
- - { name: foo_tag, tag_option: from_service }
- # calls from instanceof are kept, but this comes later
- calls:
- - [enableSummer, [true]]
- - [setSunshine, [warm]]
-
- service_override_instanceof:
- class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
- # override instanceof
- autowire: true
- autoconfigure: true
-
- parent_service:
- abstract: true
- lazy: true
-
- # instanceof will not be applied to this
- child_service:
- class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
- parent: parent_service
-
- parent_service_with_class:
- abstract: true
- class: Symfony\Component\DependencyInjection\Tests\Compiler\IntegrationTestStub
- tags:
- - { name: foo_tag, tag_option: from_parent_def }
-
- child_service_with_parent_instanceof:
- parent: parent_service_with_class
- shared: true
- inherit_tags: true
- tags:
- - { name: foo_tag, tag_option: from_child_def }
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_with_parent.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_with_parent.yml
new file mode 100644
index 0000000000000..28dec4ce91791
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_defaults_with_parent.yml
@@ -0,0 +1,10 @@
+services:
+ _defaults:
+ autowire: true
+
+ parent_service:
+ class: stdClass
+
+ child_service:
+ class: stdClass
+ parent: parent_service
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_instanceof_with_parent.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_instanceof_with_parent.yml
new file mode 100644
index 0000000000000..fb21cdf2fb674
--- /dev/null
+++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services_instanceof_with_parent.yml
@@ -0,0 +1,11 @@
+services:
+ _instanceof:
+ FooInterface:
+ autowire: true
+
+ parent_service:
+ class: stdClass
+
+ child_service:
+ class: stdClass
+ parent: parent_service
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
index 3b6ddd7fcb862..6f85d2ee16be4 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
@@ -651,20 +651,13 @@ public function testDefaults()
$this->assertArrayNotHasKey('public', $container->getDefinition('with_defaults')->getChanges());
$this->assertArrayNotHasKey('autowire', $container->getDefinition('with_defaults')->getChanges());
- $this->assertArrayNotHasKey('public', $container->getDefinition('no_defaults_child')->getChanges());
- $this->assertArrayNotHasKey('autowire', $container->getDefinition('no_defaults_child')->getChanges());
-
$container->compile();
$this->assertTrue($container->getDefinition('no_defaults')->isPublic());
- $this->assertTrue($container->getDefinition('no_defaults_child')->isPublic());
$this->assertSame(array(), $container->getDefinition('no_defaults')->getTags());
- $this->assertSame(array('bar' => array(array())), $container->getDefinition('no_defaults_child')->getTags());
- $this->assertSame(array('baz' => array(array()), 'foo' => array(array())), $container->getDefinition('with_defaults_child')->getTags());
$this->assertFalse($container->getDefinition('no_defaults')->isAutowired());
- $this->assertFalse($container->getDefinition('no_defaults_child')->isAutowired());
}
public function testNamedArguments()
@@ -694,6 +687,42 @@ public function testInstanceof()
$this->assertSame(array('foo' => array(array()), 'bar' => array(array())), $definition->getTags());
}
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
+ * @expectedExceptionMessage The service "child_service" cannot use the "parent" option in the same file where "instanceof" configuration is defined as using both is not supported. Try moving your child definitions to a different file.
+ */
+ public function testInstanceOfAndChildDefinitionNotAllowed()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+ $loader->load('services_instanceof_with_parent.xml');
+ $container->compile();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
+ * @expectedExceptionMessage The service "child_service" cannot have a "parent" and also have "autoconfigure". Try setting autoconfigure="false" for the service.
+ */
+ public function testAutoConfigureAndChildDefinitionNotAllowed()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+ $loader->load('services_autoconfigure_with_parent.xml');
+ $container->compile();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
+ * @expectedExceptionMessage The service "child_service" cannot use the "parent" option in the same file where "defaults" configuration is defined as using both is not supported. Try moving your child definitions to a different file.
+ */
+ public function testDefaultsAndChildDefinitionNotAllowed()
+ {
+ $container = new ContainerBuilder();
+ $loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
+ $loader->load('services_defaults_with_parent.xml');
+ $container->compile();
+ }
+
public function testAutoConfigureInstanceof()
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
index 87a05eb2abd1f..e20575d2aa8f7 100644
--- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
+++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
@@ -403,9 +403,6 @@ public function testDefaults()
$this->assertFalse($container->getAlias('with_defaults_aliased')->isPublic());
$this->assertFalse($container->getAlias('with_defaults_aliased_short')->isPublic());
- $this->assertArrayNotHasKey('public', $container->getDefinition('no_defaults_child')->getChanges());
- $this->assertArrayNotHasKey('autowire', $container->getDefinition('no_defaults_child')->getChanges());
-
$this->assertFalse($container->getDefinition('Acme\WithShortCutArgs')->isPublic());
$this->assertSame(array('foo' => array(array())), $container->getDefinition('Acme\WithShortCutArgs')->getTags());
$this->assertTrue($container->getDefinition('Acme\WithShortCutArgs')->isAutowired());
@@ -414,16 +411,12 @@ public function testDefaults()
$this->assertTrue($container->getDefinition('with_null')->isPublic());
$this->assertTrue($container->getDefinition('no_defaults')->isPublic());
- $this->assertTrue($container->getDefinition('no_defaults_child')->isPublic());
$this->assertSame(array(), $container->getDefinition('with_null')->getTags());
$this->assertSame(array(), $container->getDefinition('no_defaults')->getTags());
- $this->assertSame(array('bar' => array(array())), $container->getDefinition('no_defaults_child')->getTags());
- $this->assertSame(array('baz' => array(array()), 'foo' => array(array())), $container->getDefinition('with_defaults_child')->getTags());
$this->assertTrue($container->getDefinition('with_null')->isAutowired());
$this->assertFalse($container->getDefinition('no_defaults')->isAutowired());
- $this->assertFalse($container->getDefinition('no_defaults_child')->isAutowired());
}
public function testNamedArguments()
@@ -455,6 +448,42 @@ public function testInstanceof()
$this->assertSame(array('foo' => array(array()), 'bar' => array(array())), $definition->getTags());
}
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
+ * @expectedExceptionMessage The service "child_service" cannot use the "parent" option in the same file where "_instanceof" configuration is defined as using both is not supported. Try moving your child definitions to a different file.
+ */
+ public function testInstanceOfAndChildDefinitionNotAllowed()
+ {
+ $container = new ContainerBuilder();
+ $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
+ $loader->load('services_instanceof_with_parent.yml');
+ $container->compile();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
+ * @expectedExceptionMessage The service "child_service" cannot have a "parent" and also have "autoconfigure". Try setting "autoconfigure: false" for the service.
+ */
+ public function testAutoConfigureAndChildDefinitionNotAllowed()
+ {
+ $container = new ContainerBuilder();
+ $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
+ $loader->load('services_autoconfigure_with_parent.yml');
+ $container->compile();
+ }
+
+ /**
+ * @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
+ * @expectedExceptionMessage The service "child_service" cannot use the "parent" option in the same file where "_defaults" configuration is defined as using both is not supported. Try moving your child definitions to a different file.
+ */
+ public function testDefaultsAndChildDefinitionNotAllowed()
+ {
+ $container = new ContainerBuilder();
+ $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
+ $loader->load('services_defaults_with_parent.yml');
+ $container->compile();
+ }
+
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
* @expectedExceptionMessage The value of the "decorates" option for the "bar" service must be the id of the service without the "@" prefix (replace "@foo" with "foo").