Skip to content
Permalink
Browse files

bug #29995 [DI] add id of referencing service when a deprecated alias…

… is found (nicolas-grekas)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[DI] add id of referencing service when a deprecated alias is found

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

Improves #29968 a bit for DX.

Commits
-------

b124fb7 [DI] add id of referencing service when a deprecated alias is found
  • Loading branch information...
nicolas-grekas committed Jan 28, 2019
2 parents 5a8c06e + b124fb7 commit dca09750ed8366249c79baab1489015700c925f0
Showing with 58 additions and 55 deletions.
  1. +4 −4 src/Symfony/Component/DependencyInjection/Alias.php
  2. +1 −1 src/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php
  3. +19 −16 src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php
  4. +1 −1 src/Symfony/Component/DependencyInjection/Definition.php
  5. +7 −7 src/Symfony/Component/DependencyInjection/Tests/AliasTest.php
  6. +2 −2 src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveReferencesToAliasesPassTest.php
  7. +2 −2 src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
  8. +1 −1 src/Symfony/Component/DependencyInjection/Tests/DefinitionTest.php
  9. +2 −2 src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php
  10. +1 −1 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/container_alias_deprecation.php
  11. +2 −2 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_as_files.txt
  12. +4 −4 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services9_compiled.php
  13. +4 −4 src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services_errored_definition.php
  14. +1 −1 src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/deprecated_alias_definitions.xml
  15. +2 −2 src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services9.xml
  16. +1 −1 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/deprecated_alias_definitions.yml
  17. +2 −2 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services9.yml
  18. +2 −2 src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
@@ -21,7 +21,7 @@ class Alias
private $deprecated;
private $deprecationTemplate;
private static $defaultDeprecationTemplate = 'The "%service_id%" service alias is deprecated. You should stop using it, as it will soon be removed.';
private static $defaultDeprecationTemplate = 'The "%alias_id%" service alias is deprecated. You should stop using it, as it will be removed in the future.';
public function __construct(string $id, bool $public = true)
{
@@ -103,8 +103,8 @@ public function setDeprecated($status = true, $template = null)
throw new InvalidArgumentException('Invalid characters found in deprecation template.');
}
if (false === strpos($template, '%service_id%')) {
throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.');
if (false === strpos($template, '%alias_id%')) {
throw new InvalidArgumentException('The deprecation template must contain the "%alias_id%" placeholder.');
}
$this->deprecationTemplate = $template;
@@ -122,7 +122,7 @@ public function isDeprecated(): bool
public function getDeprecationMessage(string $id): string
{
return str_replace('%service_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
return str_replace('%alias_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
}
/**
@@ -86,7 +86,7 @@ public function process(ContainerBuilder $container)
protected function processValue($value, $isRoot = false)
{
if (!$value instanceof Reference) {
return parent::processValue($value);
return parent::processValue($value, $isRoot);
}
if (ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior()) {
@@ -31,6 +31,7 @@ public function process(ContainerBuilder $container)
foreach ($container->getAliases() as $id => $alias) {
$aliasId = (string) $alias;
$this->currentId = $id;
if ($aliasId !== $defId = $this->getDefinitionId($aliasId, $container)) {
$container->setAlias($id, $defId)->setPublic($alias->isPublic())->setPrivate($alias->isPrivate());
@@ -43,34 +44,36 @@ public function process(ContainerBuilder $container)
*/
protected function processValue($value, $isRoot = false)
{
if ($value instanceof Reference) {
$defId = $this->getDefinitionId($id = (string) $value, $this->container);
if ($defId !== $id) {
return new Reference($defId, $value->getInvalidBehavior());
}
if (!$value instanceof Reference) {
return parent::processValue($value, $isRoot);
}
return parent::processValue($value);
$defId = $this->getDefinitionId($id = (string) $value, $this->container);
return $defId !== $id ? new Reference($defId, $value->getInvalidBehavior()) : $value;
}
private function getDefinitionId(string $id, ContainerBuilder $container): string
{
if (!$container->hasAlias($id)) {
return $id;
}
$alias = $container->getAlias($id);
if ($alias->isDeprecated()) {
@trigger_error(sprintf('%s. It is being referenced by the "%s" %s.', rtrim($alias->getDeprecationMessage($id), '. '), $this->currentId, $container->hasDefinition($this->currentId) ? 'service' : 'alias'), E_USER_DEPRECATED);
}
$seen = [];
while ($container->hasAlias($id)) {
do {
if (isset($seen[$id])) {
throw new ServiceCircularReferenceException($id, array_merge(array_keys($seen), [$id]));
}
$seen[$id] = true;
$alias = $container->getAlias($id);
if ($alias->isDeprecated()) {
@trigger_error($alias->getDeprecationMessage($id), E_USER_DEPRECATED);
}
$id = (string) $alias;
}
$id = (string) $container->getAlias($id);
} while ($container->hasAlias($id));
return $id;
}
@@ -47,7 +47,7 @@ class Definition
protected $arguments = [];
private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.';
private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.';
/**
* @internal
@@ -52,7 +52,7 @@ public function testCanSetPublic()
public function testCanDeprecateAnAlias()
{
$alias = new Alias('foo', false);
$alias->setDeprecated(true, 'The %service_id% service is deprecated.');
$alias->setDeprecated(true, 'The %alias_id% service is deprecated.');
$this->assertTrue($alias->isDeprecated());
}
@@ -62,14 +62,14 @@ public function testItHasADefaultDeprecationMessage()
$alias = new Alias('foo', false);
$alias->setDeprecated();
$expectedMessage = 'The "foo" service alias is deprecated. You should stop using it, as it will soon be removed.';
$expectedMessage = 'The "foo" service alias is deprecated. You should stop using it, as it will be removed in the future.';
$this->assertEquals($expectedMessage, $alias->getDeprecationMessage('foo'));
}
public function testReturnsCorrectDeprecationMessage()
{
$alias = new Alias('foo', false);
$alias->setDeprecated(true, 'The "%service_id%" is deprecated.');
$alias->setDeprecated(true, 'The "%alias_id%" is deprecated.');
$expectedMessage = 'The "foo" is deprecated.';
$this->assertEquals($expectedMessage, $alias->getDeprecationMessage('foo'));
@@ -101,10 +101,10 @@ public function testCannotDeprecateWithAnInvalidTemplate($message)
public function invalidDeprecationMessageProvider()
{
return [
"With \rs" => ["invalid \r message %service_id%"],
"With \ns" => ["invalid \n message %service_id%"],
'With */s' => ['invalid */ message %service_id%'],
'message not containing required %service_id% variable' => ['this is deprecated'],
"With \rs" => ["invalid \r message %alias_id%"],
"With \ns" => ["invalid \n message %alias_id%"],
'With */s' => ['invalid */ message %alias_id%'],
'message not containing required %alias_id% variable' => ['this is deprecated'],
];
}
}
@@ -85,7 +85,7 @@ public function testResolveFactory()
/**
* @group legacy
* @expectedDeprecation The "deprecated_foo_alias" service alias is deprecated. You should stop using it, as it will soon be removed.
* @expectedDeprecation The "deprecated_foo_alias" service alias is deprecated. You should stop using it, as it will be removed in the future. It is being referenced by the "alias" alias.
*/
public function testDeprecationNoticeWhenReferencedByAlias()
{
@@ -105,7 +105,7 @@ public function testDeprecationNoticeWhenReferencedByAlias()
/**
* @group legacy
* @expectedDeprecation The "foo_aliased" service alias is deprecated. You should stop using it, as it will soon be removed.
* @expectedDeprecation The "foo_aliased" service alias is deprecated. You should stop using it, as it will be removed in the future. It is being referenced by the "definition" service.
*/
public function testDeprecationNoticeWhenReferencedByDefinition()
{
@@ -88,7 +88,7 @@ public function testDefinitions()
/**
* @group legacy
* @expectedDeprecation The "deprecated_foo" service is deprecated. You should stop using it, as it will soon be removed.
* @expectedDeprecation The "deprecated_foo" service is deprecated. You should stop using it, as it will be removed in the future.
*/
public function testCreateDeprecatedService()
{
@@ -261,7 +261,7 @@ public function testAliases()
/**
* @group legacy
* @expectedDeprecation The "foobar" service alias is deprecated. You should stop using it, as it will soon be removed.
* @expectedDeprecation The "foobar" service alias is deprecated. You should stop using it, as it will be removed in the future.
*/
public function testDeprecatedAlias()
{
@@ -164,7 +164,7 @@ public function testSetIsDeprecated()
$this->assertFalse($def->isDeprecated(), '->isDeprecated() returns false by default');
$this->assertSame($def, $def->setDeprecated(true), '->setDeprecated() implements a fluent interface');
$this->assertTrue($def->isDeprecated(), '->isDeprecated() returns true if the instance should not be used anymore.');
$this->assertSame('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', $def->getDeprecationMessage('deprecated_service'), '->getDeprecationMessage() should return a formatted message template');
$this->assertSame('The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.', $def->getDeprecationMessage('deprecated_service'), '->getDeprecationMessage() should return a formatted message template');
}
/**
@@ -327,7 +327,7 @@ public function testAliases()
/**
* @group legacy
* @expectedDeprecation The "alias_for_foo_deprecated" service alias is deprecated. You should stop using it, as it will soon be removed.
* @expectedDeprecation The "alias_for_foo_deprecated" service alias is deprecated. You should stop using it, as it will be removed in the future.
*/
public function testAliasesDeprecation()
{
@@ -1067,7 +1067,7 @@ public function testAdawsonContainer()
* This test checks the trigger of a deprecation note and should not be removed in major releases.
*
* @group legacy
* @expectedDeprecation The "foo" service is deprecated. You should stop using it, as it will soon be removed.
* @expectedDeprecation The "foo" service is deprecated. You should stop using it, as it will be removed in the future.
*/
public function testPrivateServiceTriggersDeprecation()
{
@@ -66,7 +66,7 @@ protected function getFooService()
*/
protected function getAliasForFooDeprecatedService()
{
@trigger_error('The "alias_for_foo_deprecated" service alias is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
@trigger_error('The "alias_for_foo_deprecated" service alias is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
return $this->get('foo');
}
@@ -124,7 +124,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the public 'deprecated_service' shared service.

@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);

return $this->services['deprecated_service'] = new \stdClass();

@@ -156,7 +156,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
// Returns the private 'factory_simple' shared service.

@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);

return new \SimpleFactoryClass('foo');

@@ -206,11 +206,11 @@ protected function getDecoratorServiceWithNameService()
*
* @return \stdClass
*
* @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.
* @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.
*/
protected function getDeprecatedServiceService()
{
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
return $this->services['deprecated_service'] = new \stdClass();
}
@@ -400,11 +400,11 @@ protected function getTaggedIteratorService()
*
* @return \SimpleFactoryClass
*
* @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.
* @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.
*/
protected function getFactorySimpleService()
{
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
return new \SimpleFactoryClass('foo');
}
@@ -206,11 +206,11 @@ protected function getDecoratorServiceWithNameService()
*
* @return \stdClass
*
* @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.
* @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.
*/
protected function getDeprecatedServiceService()
{
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
return $this->services['deprecated_service'] = new \stdClass();
}
@@ -400,11 +400,11 @@ protected function getTaggedIteratorService()
*
* @return \SimpleFactoryClass
*
* @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.
* @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.
*/
protected function getFactorySimpleService()
{
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
return new \SimpleFactoryClass('foo');
}
@@ -7,7 +7,7 @@
<deprecated />
</service>
<service id="alias_for_foobar" alias="foobar">
<deprecated>The "%service_id%" service alias is deprecated.</deprecated>
<deprecated>The "%alias_id%" service alias is deprecated.</deprecated>
</service>
</services>
</container>
@@ -97,7 +97,7 @@
<service id="decorator_service" class="stdClass" public="true" decorates="decorated"/>
<service id="decorator_service_with_name" class="stdClass" public="true" decorates="decorated" decoration-inner-name="decorated.pif-pouf"/>
<service id="deprecated_service" class="stdClass" public="true">
<deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.</deprecated>
<deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.</deprecated>
</service>
<service id="new_factory" class="FactoryClass" public="false">
<property name="foo">bar</property>
@@ -114,7 +114,7 @@
</service>
<service id="factory_simple" class="SimpleFactoryClass" public="false">
<argument>foo</argument>
<deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.</deprecated>
<deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.</deprecated>
</service>
<service id="factory_service_simple" class="Bar" public="true">
<factory service="factory_simple" method="getInstance"/>
@@ -1,4 +1,4 @@
services:
alias_for_foobar:
alias: foobar
deprecated: The "%service_id%" service alias is deprecated.
deprecated: The "%alias_id%" service alias is deprecated.
@@ -103,7 +103,7 @@ services:
public: true
deprecated_service:
class: stdClass
deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.
deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.
public: true
new_factory:
class: FactoryClass
@@ -124,7 +124,7 @@ services:
public: true
factory_simple:
class: SimpleFactoryClass
deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.
deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.
public: false
arguments: ['foo']
factory_service_simple:
@@ -343,7 +343,7 @@ public function testDeprecated()
$loader->load('services_deprecated.xml');
$this->assertTrue($container->getDefinition('foo')->isDeprecated());
$message = 'The "foo" service is deprecated. You should stop using it, as it will soon be removed.';
$message = 'The "foo" service is deprecated. You should stop using it, as it will be removed in the future.';
$this->assertSame($message, $container->getDefinition('foo')->getDeprecationMessage('foo'));
$this->assertTrue($container->getDefinition('bar')->isDeprecated());
@@ -358,7 +358,7 @@ public function testDeprecatedAliases()
$loader->load('deprecated_alias_definitions.xml');
$this->assertTrue($container->getAlias('alias_for_foo')->isDeprecated());
$message = 'The "alias_for_foo" service alias is deprecated. You should stop using it, as it will soon be removed.';
$message = 'The "alias_for_foo" service alias is deprecated. You should stop using it, as it will be removed in the future.';
$this->assertSame($message, $container->getAlias('alias_for_foo')->getDeprecationMessage('alias_for_foo'));
$this->assertTrue($container->getAlias('alias_for_foobar')->isDeprecated());

0 comments on commit dca0975

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.