Making tags under _defaults always apply and removing inherit_tags entirely

Now that inherit_tags has been removed, 3.3 has the same functionality as 3.2: tags
are *never* cascaded from parent to child (but you tags do inherit from defaults
to a service and instanceof to a service).
This commit is contained in:
Ryan Weaver 2017-04-25 22:22:00 -04:00
parent 7010a7a76b
commit 037a782b91
16 changed files with 10 additions and 184 deletions

View File

@ -22,8 +22,7 @@ CHANGELOG
* added "iterator" argument type for lazy iteration over a set of values and services
* added "closure-proxy" argument type for turning services' methods into lazy callables
* added file-wide configurable defaults for service attributes "public", "tags",
"autowire" and "inherit-tags"
* added "inherit-tags" service attribute to control tags' inheritance from parent context
"autowire" and "autoconfigure"
* made the "class" attribute optional, using the "id" as fallback
* using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
will not be supported anymore in 4.0

View File

@ -23,7 +23,6 @@ use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
class ChildDefinition extends Definition
{
private $parent;
private $inheritTags = false;
/**
* @param string $parent The id of Definition instance to decorate
@ -57,30 +56,6 @@ class ChildDefinition extends Definition
return $this;
}
/**
* Sets whether tags should be inherited from the parent or not.
*
* @param bool $boolean
*
* @return $this
*/
public function setInheritTags($boolean)
{
$this->inheritTags = (bool) $boolean;
return $this;
}
/**
* Returns whether tags should be inherited from the parent or not.
*
* @return bool
*/
public function getInheritTags()
{
return $this->inheritTags;
}
/**
* Gets an argument to pass to the service constructor/factory method.
*

View File

@ -43,7 +43,6 @@ class PassConfig
100 => array(
$resolveClassPass = new ResolveClassPass(),
new ResolveInstanceofConditionalsPass(),
new ResolveTagsInheritancePass(),
),
);

View File

@ -77,7 +77,7 @@ class ResolveInstanceofConditionalsPass implements CompilerPassInterface
foreach ($instanceofDefs as $key => $instanceofDef) {
/** @var ChildDefinition $instanceofDef */
$instanceofDef = clone $instanceofDef;
$instanceofDef->setAbstract(true)->setInheritTags(false)->setParent($parent ?: 'abstract.instanceof.'.$id);
$instanceofDef->setAbstract(true)->setParent($parent ?: 'abstract.instanceof.'.$id);
$parent = 'instanceof.'.$interface.'.'.$key.'.'.$id;
$container->setDefinition($parent, $instanceofDef);
$instanceofTags[] = $instanceofDef->getTags();

View File

@ -1,74 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
/**
* Applies tags inheritance to definitions.
*
* @author Nicolas Grekas <p@tchwork.com>
*/
class ResolveTagsInheritancePass extends AbstractRecursivePass
{
private $abstractInheritedParents = array();
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
try {
parent::process($container);
foreach ($this->abstractInheritedParents as $id) {
$container->findDefinition($id)->setTags(array());
}
} finally {
$this->abstractInheritedParents = array();
}
}
/**
* {@inheritdoc}
*/
protected function processValue($value, $isRoot = false)
{
if (!$value instanceof ChildDefinition || !$value->getInheritTags()) {
return parent::processValue($value, $isRoot);
}
$value->setInheritTags(false);
if (!$this->container->has($parent = $value->getParent())) {
throw new RuntimeException(sprintf('Parent definition "%s" does not exist.', $parent));
}
$parentDef = $this->container->findDefinition($parent);
if ($parentDef->isAbstract()) {
$this->abstractInheritedParents[$parent] = $parent;
}
if ($parentDef instanceof ChildDefinition) {
$this->processValue($parentDef);
}
foreach ($parentDef->getTags() as $k => $v) {
foreach ($v as $v) {
$value->addTag($k, $v);
}
}
return parent::processValue($value, $isRoot);
}
}

View File

@ -178,9 +178,6 @@ class XmlFileLoader extends FileLoader
if ($defaultsNode->hasAttribute('public')) {
$defaults['public'] = XmlUtils::phpize($defaultsNode->getAttribute('public'));
}
if ($defaultsNode->hasAttribute('inherit-tags')) {
$defaults['inherit-tags'] = XmlUtils::phpize($defaultsNode->getAttribute('inherit-tags'));
}
if ($defaultsNode->hasAttribute('autoconfigure')) {
$defaults['autoconfigure'] = XmlUtils::phpize($defaultsNode->getAttribute('autoconfigure'));
}
@ -225,13 +222,6 @@ class XmlFileLoader extends FileLoader
}
$definition = new ChildDefinition($parent);
if ($value = $service->getAttribute('inherit-tags')) {
$definition->setInheritTags(XmlUtils::phpize($value));
} elseif (isset($defaults['inherit-tags'])) {
$definition->setInheritTags($defaults['inherit-tags']);
}
$defaults = array();
} else {
$definition = new Definition();
@ -318,13 +308,7 @@ class XmlFileLoader extends FileLoader
$tags = $this->getChildren($service, 'tag');
if (empty($defaults['tags'])) {
// no-op
} elseif (!$value = $service->getAttribute('inherit-tags')) {
if (!$tags) {
$tags = $defaults['tags'];
}
} elseif (XmlUtils::phpize($value)) {
if (!empty($defaults['tags'])) {
$tags = array_merge($tags, $defaults['tags']);
}

View File

@ -51,7 +51,6 @@ class YamlFileLoader extends FileLoader
'configurator' => 'configurator',
'calls' => 'calls',
'tags' => 'tags',
'inherit_tags' => 'inherit_tags',
'decorates' => 'decorates',
'decoration_inner_name' => 'decoration_inner_name',
'decoration_priority' => 'decoration_priority',
@ -74,7 +73,6 @@ class YamlFileLoader extends FileLoader
'configurator' => 'configurator',
'calls' => 'calls',
'tags' => 'tags',
'inherit_tags' => 'inherit_tags',
'autowire' => 'autowire',
'autoconfigure' => 'autoconfigure',
);
@ -93,7 +91,6 @@ class YamlFileLoader extends FileLoader
private static $defaultsKeywords = array(
'public' => 'public',
'tags' => 'tags',
'inherit_tags' => 'inherit_tags',
'autowire' => 'autowire',
'autoconfigure' => 'autoconfigure',
);
@ -365,12 +362,6 @@ class YamlFileLoader extends FileLoader
}
$definition = new ChildDefinition($service['parent']);
$inheritTag = isset($service['inherit_tags']) ? $service['inherit_tags'] : (isset($defaults['inherit_tags']) ? $defaults['inherit_tags'] : null);
if (null !== $inheritTag) {
$definition->setInheritTags($inheritTag);
}
$defaults = array();
} else {
$definition = new Definition();
@ -458,13 +449,7 @@ class YamlFileLoader extends FileLoader
throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
}
if (!isset($defaults['tags'])) {
// no-op
} elseif (!isset($service['inherit_tags'])) {
if (!isset($service['tags'])) {
$tags = $defaults['tags'];
}
} elseif ($service['inherit_tags']) {
if (isset($defaults['tags'])) {
$tags = array_merge($tags, $defaults['tags']);
}

View File

@ -103,7 +103,6 @@
</xsd:choice>
<xsd:attribute name="public" type="boolean" />
<xsd:attribute name="autowire" type="boolean" />
<xsd:attribute name="inherit-tags" type="boolean" />
<xsd:attribute name="autoconfigure" type="boolean" />
</xsd:complexType>
@ -132,7 +131,6 @@
<xsd:attribute name="decoration-inner-name" type="xsd:string" />
<xsd:attribute name="decoration-priority" type="xsd:integer" />
<xsd:attribute name="autowire" type="boolean" />
<xsd:attribute name="inherit-tags" type="boolean" />
<xsd:attribute name="autoconfigure" type="boolean" />
</xsd:complexType>
@ -169,7 +167,6 @@
<xsd:attribute name="abstract" type="boolean" />
<xsd:attribute name="parent" type="xsd:string" />
<xsd:attribute name="autowire" type="boolean" />
<xsd:attribute name="inherit-tags" type="boolean" />
<xsd:attribute name="autoconfigure" type="boolean" />
</xsd:complexType>

View File

@ -15,7 +15,6 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
use Symfony\Component\DependencyInjection\Compiler\ResolveDefinitionTemplatesPass;
use Symfony\Component\DependencyInjection\Compiler\ResolveTagsInheritancePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ResolveInstanceofConditionalsPassTest extends TestCase
@ -35,7 +34,6 @@ class ResolveInstanceofConditionalsPassTest extends TestCase
$this->assertEmpty($def->getInstanceofConditionals());
$this->assertInstanceof(ChildDefinition::class, $def);
$this->assertTrue($def->isAutowired());
$this->assertFalse($def->getInheritTags());
$this->assertSame($parent, $def->getParent());
$this->assertSame(array('tag' => array(array()), 'baz' => array(array('attr' => 123))), $def->getTags());
@ -121,7 +119,6 @@ class ResolveInstanceofConditionalsPassTest extends TestCase
->setFactory('autoconfigured_factory');
(new ResolveInstanceofConditionalsPass())->process($container);
(new ResolveTagsInheritancePass())->process($container);
(new ResolveDefinitionTemplatesPass())->process($container);
$def = $container->getDefinition('normal_service');

View File

@ -1,34 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\ResolveTagsInheritancePass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ResolveTagsInheritancePassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();
$container->register('grandpa', self::class)->addTag('g');
$container->setDefinition('parent', new ChildDefinition('grandpa'))->addTag('p')->setInheritTags(true)->setAbstract(true);
$container->setDefinition('child', new ChildDefinition('parent'))->setInheritTags(true);
(new ResolveTagsInheritancePass())->process($container);
$expected = array('p' => array(array()), 'g' => array(array()));
$this->assertSame($expected, $container->getDefinition('child')->getTags());
$this->assertSame(array(), $container->getDefinition('parent')->getTags());
}
}

View File

@ -6,7 +6,7 @@
</defaults>
<service id="with_defaults" class="Foo" />
<service id="no_defaults" class="Foo" public="true" autowire="false" inherit-tags="false">
<service id="no_defaults" class="Foo" public="true" autowire="false">
</service>
</services>
</container>

View File

@ -16,8 +16,7 @@ services:
# 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 }
- { name: from_defaults }
# calls from instanceof are kept, but this comes later
calls:
# first call is from instanceof

View File

@ -14,7 +14,6 @@ services:
class: Foo
public: true
autowire: ~
inherit_tags: false
no_defaults:
class: Foo

View File

@ -4,4 +4,3 @@ services:
Foo\Bar:
tags: invalid
inherit_tags: true

View File

@ -655,7 +655,7 @@ class XmlFileLoaderTest extends TestCase
$this->assertTrue($container->getDefinition('no_defaults')->isPublic());
$this->assertSame(array(), $container->getDefinition('no_defaults')->getTags());
$this->assertSame(array('foo' => array(array())), $container->getDefinition('no_defaults')->getTags());
$this->assertFalse($container->getDefinition('no_defaults')->isAutowired());
}

View File

@ -412,8 +412,9 @@ class YamlFileLoaderTest extends TestCase
$this->assertTrue($container->getDefinition('with_null')->isPublic());
$this->assertTrue($container->getDefinition('no_defaults')->isPublic());
$this->assertSame(array(), $container->getDefinition('with_null')->getTags());
$this->assertSame(array(), $container->getDefinition('no_defaults')->getTags());
// foo tag is inherited from defaults
$this->assertSame(array('foo' => array(array())), $container->getDefinition('with_null')->getTags());
$this->assertSame(array('foo' => array(array())), $container->getDefinition('no_defaults')->getTags());
$this->assertTrue($container->getDefinition('with_null')->isAutowired());
$this->assertFalse($container->getDefinition('no_defaults')->isAutowired());