Skip to content

Commit 6f15885

Browse files
committed
replace DefinitionDecorator with ChildDefinition
The DefinitionDecorator class does not deal with decorated services. It reflects a parent-child-relationship between definitions instead. To avoid confusion, this commit deprecates the existing DefinitionDecorator class and introduces a new ChildDefinition class as replacement.
1 parent 42004d3 commit 6f15885

11 files changed

+382
-221
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
3.3.0
5+
-----
6+
7+
* deprecated the `DefinitionDecorator` class in favor of `ChildDefinition`
8+
49
3.2.0
510
-----
611

ChildDefinition.php

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection;
13+
14+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
15+
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
16+
17+
/**
18+
* This definition extends another definition.
19+
*
20+
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
21+
*/
22+
class ChildDefinition extends Definition
23+
{
24+
private $parent;
25+
private $changes = array();
26+
27+
/**
28+
* @param string $parent The id of Definition instance to decorate
29+
*/
30+
public function __construct($parent)
31+
{
32+
parent::__construct();
33+
34+
$this->parent = $parent;
35+
}
36+
37+
/**
38+
* Returns the Definition being decorated.
39+
*
40+
* @return string
41+
*/
42+
public function getParent()
43+
{
44+
return $this->parent;
45+
}
46+
47+
/**
48+
* Returns all changes tracked for the Definition object.
49+
*
50+
* @return array An array of changes for this Definition
51+
*/
52+
public function getChanges()
53+
{
54+
return $this->changes;
55+
}
56+
57+
/**
58+
* {@inheritdoc}
59+
*/
60+
public function setClass($class)
61+
{
62+
$this->changes['class'] = true;
63+
64+
return parent::setClass($class);
65+
}
66+
67+
/**
68+
* {@inheritdoc}
69+
*/
70+
public function setFactory($callable)
71+
{
72+
$this->changes['factory'] = true;
73+
74+
return parent::setFactory($callable);
75+
}
76+
77+
/**
78+
* {@inheritdoc}
79+
*/
80+
public function setConfigurator($callable)
81+
{
82+
$this->changes['configurator'] = true;
83+
84+
return parent::setConfigurator($callable);
85+
}
86+
87+
/**
88+
* {@inheritdoc}
89+
*/
90+
public function setFile($file)
91+
{
92+
$this->changes['file'] = true;
93+
94+
return parent::setFile($file);
95+
}
96+
97+
/**
98+
* {@inheritdoc}
99+
*/
100+
public function setPublic($boolean)
101+
{
102+
$this->changes['public'] = true;
103+
104+
return parent::setPublic($boolean);
105+
}
106+
107+
/**
108+
* {@inheritdoc}
109+
*/
110+
public function setLazy($boolean)
111+
{
112+
$this->changes['lazy'] = true;
113+
114+
return parent::setLazy($boolean);
115+
}
116+
117+
/**
118+
* {@inheritdoc}
119+
*/
120+
public function setDecoratedService($id, $renamedId = null, $priority = 0)
121+
{
122+
$this->changes['decorated_service'] = true;
123+
124+
return parent::setDecoratedService($id, $renamedId, $priority);
125+
}
126+
127+
/**
128+
* {@inheritdoc}
129+
*/
130+
public function setDeprecated($boolean = true, $template = null)
131+
{
132+
$this->changes['deprecated'] = true;
133+
134+
return parent::setDeprecated($boolean, $template);
135+
}
136+
137+
/**
138+
* {@inheritdoc}
139+
*/
140+
public function setAutowired($autowired)
141+
{
142+
$this->changes['autowire'] = true;
143+
144+
return parent::setAutowired($autowired);
145+
}
146+
147+
/**
148+
* Gets an argument to pass to the service constructor/factory method.
149+
*
150+
* If replaceArgument() has been used to replace an argument, this method
151+
* will return the replacement value.
152+
*
153+
* @param int $index
154+
*
155+
* @return mixed The argument value
156+
*
157+
* @throws OutOfBoundsException When the argument does not exist
158+
*/
159+
public function getArgument($index)
160+
{
161+
if (array_key_exists('index_'.$index, $this->arguments)) {
162+
return $this->arguments['index_'.$index];
163+
}
164+
165+
$lastIndex = count(array_filter(array_keys($this->arguments), 'is_int')) - 1;
166+
167+
if ($index < 0 || $index > $lastIndex) {
168+
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, $lastIndex));
169+
}
170+
171+
return $this->arguments[$index];
172+
}
173+
174+
/**
175+
* You should always use this method when overwriting existing arguments
176+
* of the parent definition.
177+
*
178+
* If you directly call setArguments() keep in mind that you must follow
179+
* certain conventions when you want to overwrite the arguments of the
180+
* parent definition, otherwise your arguments will only be appended.
181+
*
182+
* @param int $index
183+
* @param mixed $value
184+
*
185+
* @return self the current instance
186+
*
187+
* @throws InvalidArgumentException when $index isn't an integer
188+
*/
189+
public function replaceArgument($index, $value)
190+
{
191+
if (!is_int($index)) {
192+
throw new InvalidArgumentException('$index must be an integer.');
193+
}
194+
195+
$this->arguments['index_'.$index] = $value;
196+
197+
return $this;
198+
}
199+
}

Compiler/ResolveDefinitionTemplatesPass.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Compiler;
1313

14+
use Symfony\Component\DependencyInjection\ChildDefinition;
1415
use Symfony\Component\DependencyInjection\Definition;
15-
use Symfony\Component\DependencyInjection\DefinitionDecorator;
1616
use Symfony\Component\DependencyInjection\ContainerBuilder;
1717
use Symfony\Component\DependencyInjection\Exception\ExceptionInterface;
1818
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
1919

2020
/**
21-
* This replaces all DefinitionDecorator instances with their equivalent fully
21+
* This replaces all ChildDefinition instances with their equivalent fully
2222
* merged Definition instance.
2323
*
2424
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
@@ -31,7 +31,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
3131
private $currentId;
3232

3333
/**
34-
* Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
34+
* Process the ContainerBuilder to replace ChildDefinition instances with their real Definition instances.
3535
*
3636
* @param ContainerBuilder $container
3737
*/
@@ -64,7 +64,7 @@ private function resolveArguments(ContainerBuilder $container, array $arguments,
6464
if (is_array($argument)) {
6565
$arguments[$k] = $this->resolveArguments($container, $argument);
6666
} elseif ($argument instanceof Definition) {
67-
if ($argument instanceof DefinitionDecorator) {
67+
if ($argument instanceof ChildDefinition) {
6868
$arguments[$k] = $argument = $this->resolveDefinition($container, $argument);
6969
if ($isRoot) {
7070
$container->setDefinition($k, $argument);
@@ -88,14 +88,14 @@ private function resolveArguments(ContainerBuilder $container, array $arguments,
8888
/**
8989
* Resolves the definition.
9090
*
91-
* @param ContainerBuilder $container The ContainerBuilder
92-
* @param DefinitionDecorator $definition
91+
* @param ContainerBuilder $container The ContainerBuilder
92+
* @param ChildDefinition $definition
9393
*
9494
* @return Definition
9595
*
9696
* @throws \RuntimeException When the definition is invalid
9797
*/
98-
private function resolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition)
98+
private function resolveDefinition(ContainerBuilder $container, ChildDefinition $definition)
9999
{
100100
try {
101101
return $this->doResolveDefinition($container, $definition);
@@ -108,14 +108,14 @@ private function resolveDefinition(ContainerBuilder $container, DefinitionDecora
108108
}
109109
}
110110

111-
private function doResolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition)
111+
private function doResolveDefinition(ContainerBuilder $container, ChildDefinition $definition)
112112
{
113113
if (!$container->has($parent = $definition->getParent())) {
114114
throw new RuntimeException(sprintf('Parent definition "%s" does not exist.', $parent));
115115
}
116116

117117
$parentDef = $container->findDefinition($parent);
118-
if ($parentDef instanceof DefinitionDecorator) {
118+
if ($parentDef instanceof ChildDefinition) {
119119
$id = $this->currentId;
120120
$this->currentId = $parent;
121121
$parentDef = $this->resolveDefinition($container, $parentDef);

ContainerBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ public function findDefinition($id)
851851
*/
852852
private function createService(Definition $definition, $id, $tryProxy = true)
853853
{
854-
if ($definition instanceof DefinitionDecorator) {
854+
if ($definition instanceof ChildDefinition) {
855855
throw new RuntimeException(sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id));
856856
}
857857

0 commit comments

Comments
 (0)