diff --git a/src/Symfony/Component/DependencyInjection/ChildDefinition.php b/src/Symfony/Component/DependencyInjection/ChildDefinition.php index bafcd3b7b87bf..b75124f61977f 100644 --- a/src/Symfony/Component/DependencyInjection/ChildDefinition.php +++ b/src/Symfony/Component/DependencyInjection/ChildDefinition.php @@ -23,15 +23,12 @@ class ChildDefinition extends Definition { private $parent; private $inheritTags = false; - private $changes = array(); /** * @param string $parent The id of Definition instance to decorate */ public function __construct($parent) { - parent::__construct(); - $this->parent = $parent; } @@ -46,13 +43,17 @@ public function getParent() } /** - * Returns all changes tracked for the Definition object. + * Sets the Definition being decorated. + * + * @param string $parent * - * @return array An array of changes for this Definition + * @return $this */ - public function getChanges() + public function setParent($parent) { - return $this->changes; + $this->parent = $parent; + + return $this; } /** @@ -79,116 +80,6 @@ public function getInheritTags() return $this->inheritTags; } - /** - * {@inheritdoc} - */ - public function setClass($class) - { - $this->changes['class'] = true; - - return parent::setClass($class); - } - - /** - * {@inheritdoc} - */ - public function setFactory($callable) - { - $this->changes['factory'] = true; - - return parent::setFactory($callable); - } - - /** - * {@inheritdoc} - */ - public function setConfigurator($callable) - { - $this->changes['configurator'] = true; - - return parent::setConfigurator($callable); - } - - /** - * {@inheritdoc} - */ - public function setFile($file) - { - $this->changes['file'] = true; - - return parent::setFile($file); - } - - /** - * {@inheritdoc} - */ - public function setShared($boolean) - { - $this->changes['shared'] = true; - - return parent::setShared($boolean); - } - - /** - * {@inheritdoc} - */ - public function setPublic($boolean) - { - $this->changes['public'] = true; - - return parent::setPublic($boolean); - } - - /** - * {@inheritdoc} - */ - public function setLazy($boolean) - { - $this->changes['lazy'] = true; - - return parent::setLazy($boolean); - } - - /** - * {@inheritdoc} - */ - public function setAbstract($boolean) - { - $this->changes['abstract'] = true; - - return parent::setAbstract($boolean); - } - - /** - * {@inheritdoc} - */ - public function setDecoratedService($id, $renamedId = null, $priority = 0) - { - $this->changes['decorated_service'] = true; - - return parent::setDecoratedService($id, $renamedId, $priority); - } - - /** - * {@inheritdoc} - */ - public function setDeprecated($boolean = true, $template = null) - { - $this->changes['deprecated'] = true; - - return parent::setDeprecated($boolean, $template); - } - - /** - * {@inheritdoc} - */ - public function setAutowired($autowired) - { - $this->changes['autowired'] = true; - - return parent::setAutowired($autowired); - } - /** * Gets an argument to pass to the service constructor/factory method. * diff --git a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php index 16d0d741ae086..8ded4ba6d1cdf 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/AbstractRecursivePass.php @@ -65,11 +65,12 @@ protected function processValue($value, $isRoot = false) $value->setProperties($this->processValue($value->getProperties())); $value->setMethodCalls($this->processValue($value->getMethodCalls())); - if ($v = $value->getFactory()) { - $value->setFactory($this->processValue($v)); + $changes = $value->getChanges(); + if (isset($changes['factory'])) { + $value->setFactory($this->processValue($value->getFactory())); } - if ($v = $value->getConfigurator()) { - $value->setConfigurator($this->processValue($v)); + if (isset($changes['configurator'])) { + $value->setConfigurator($this->processValue($value->getConfigurator())); } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php b/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php index 47402b8ad8a90..b05012a3f12b2 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php @@ -42,7 +42,8 @@ public function __construct() $this->beforeOptimizationPasses = array( 100 => array( $resolveClassPass = new ResolveClassPass(), - new ResolveDefinitionInheritancePass(), + new ResolveInstanceofConditionalsPass(), + new ResolveTagsInheritancePass(), ), ); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionInheritancePass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionInheritancePass.php deleted file mode 100644 index f06b19e33b44f..0000000000000 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionInheritancePass.php +++ /dev/null @@ -1,99 +0,0 @@ - - * - * 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\Definition; - -/** - * Applies tags and instanceof inheritance to definitions. - * - * @author Nicolas Grekas
- */ -class ResolveDefinitionInheritancePass extends AbstractRecursivePass -{ - protected function processValue($value, $isRoot = false) - { - if (!$value instanceof Definition) { - return parent::processValue($value, $isRoot); - } - - $class = $value instanceof ChildDefinition ? $this->resolveDefinition($value) : $value->getClass(); - - if (!$class || false !== strpos($class, '%') || !$instanceof = $value->getInstanceofConditionals()) { - return parent::processValue($value, $isRoot); - } - $value->setInstanceofConditionals(array()); - - foreach ($instanceof as $interface => $definition) { - if ($interface !== $class && (!$this->container->getReflectionClass($interface) || !$this->container->getReflectionClass($class))) { - continue; - } - if ($interface === $class || is_subclass_of($class, $interface)) { - $this->mergeDefinition($value, $definition); - } - } - - return parent::processValue($value, $isRoot); - } - - /** - * Populates the class and tags from parent definitions. - */ - private function resolveDefinition(ChildDefinition $definition) - { - if (!$this->container->has($parent = $definition->getParent())) { - return; - } - - $parentDef = $this->container->findDefinition($parent); - $class = $parentDef instanceof ChildDefinition ? $this->resolveDefinition($parentDef) : $parentDef->getClass(); - $class = $definition->getClass() ?: $class; - - // append parent tags when inheriting is enabled - if ($definition->getInheritTags()) { - $definition->setInheritTags(false); - - foreach ($parentDef->getTags() as $k => $v) { - foreach ($v as $v) { - $definition->addTag($k, $v); - } - } - } - - return $class; - } - - private function mergeDefinition(Definition $def, ChildDefinition $definition) - { - $changes = $definition->getChanges(); - if (isset($changes['shared'])) { - $def->setShared($definition->isShared()); - } - if (isset($changes['abstract'])) { - $def->setAbstract($definition->isAbstract()); - } - - ResolveDefinitionTemplatesPass::mergeDefinition($def, $definition); - - // prepend instanceof tags - $tailTags = $def->getTags(); - if ($headTags = $definition->getTags()) { - $def->setTags($headTags); - foreach ($tailTags as $k => $v) { - foreach ($v as $v) { - $def->addTag($k, $v); - } - } - } - } -} diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php index 7d9f7da4b8452..1b4d7b7da1163 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php @@ -84,7 +84,7 @@ private function doResolveDefinition(ChildDefinition $definition) $def = new Definition(); // merge in parent definition - // purposely ignored attributes: abstract, tags + // purposely ignored attributes: abstract, shared, tags $def->setClass($parentDef->getClass()); $def->setArguments($parentDef->getArguments()); $def->setMethodCalls($parentDef->getMethodCalls()); @@ -101,27 +101,8 @@ private function doResolveDefinition(ChildDefinition $definition) $def->setPublic($parentDef->isPublic()); $def->setLazy($parentDef->isLazy()); $def->setAutowired($parentDef->isAutowired()); + $def->setChanges($parentDef->getChanges()); - self::mergeDefinition($def, $definition); - - // merge autowiring types - foreach ($definition->getAutowiringTypes(false) as $autowiringType) { - $def->addAutowiringType($autowiringType); - } - - // these attributes are always taken from the child - $def->setAbstract($definition->isAbstract()); - $def->setShared($definition->isShared()); - $def->setTags($definition->getTags()); - - return $def; - } - - /** - * @internal - */ - public static function mergeDefinition(Definition $def, ChildDefinition $definition) - { // overwrite with values specified in the decorator $changes = $definition->getChanges(); if (isset($changes['class'])) { @@ -148,6 +129,9 @@ public static function mergeDefinition(Definition $def, ChildDefinition $definit if (isset($changes['autowired'])) { $def->setAutowired($definition->isAutowired()); } + if (isset($changes['shared'])) { + $def->setShared($definition->isShared()); + } if (isset($changes['decorated_service'])) { $decoratedService = $definition->getDecoratedService(); if (null === $decoratedService) { @@ -182,5 +166,16 @@ public static function mergeDefinition(Definition $def, ChildDefinition $definit if ($calls = $definition->getMethodCalls()) { $def->setMethodCalls(array_merge($def->getMethodCalls(), $calls)); } + + // merge autowiring types + foreach ($definition->getAutowiringTypes(false) as $autowiringType) { + $def->addAutowiringType($autowiringType); + } + + // these attributes are always taken from the child + $def->setAbstract($definition->isAbstract()); + $def->setTags($definition->getTags()); + + return $def; } } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php new file mode 100644 index 0000000000000..940d113c0b9b4 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveInstanceofConditionalsPass.php @@ -0,0 +1,91 @@ + + * + * 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\Definition; + +/** + * Applies instanceof conditionals to definitions. + * + * @author Nicolas Grekas
+ */ +class ResolveInstanceofConditionalsPass implements CompilerPassInterface +{ + /** + * {@inheritdoc} + */ + public function process(ContainerBuilder $container) + { + $didProcess = false; + foreach ($container->getDefinitions() as $id => $definition) { + if ($definition instanceof ChildDefinition) { + // don't apply "instanceof" to children: it will be applied to their parent + continue; + } + if ($definition !== $processedDefinition = $this->processDefinition($container, $id, $definition)) { + $didProcess = true; + $container->setDefinition($id, $processedDefinition); + } + } + if ($didProcess) { + $container->register('abstract.'.__CLASS__, '')->setAbstract(true); + } + } + + private function processDefinition(ContainerBuilder $container, $id, Definition $definition) + { + if (!$instanceofConditionals = $definition->getInstanceofConditionals()) { + return $definition; + } + if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) { + return $definition; + } + + $definition->setInstanceofConditionals(array()); + $instanceofParent = null; + $parent = 'abstract.'.__CLASS__; + $shared = null; + + foreach ($instanceofConditionals as $interface => $instanceofDef) { + if ($interface !== $class && (!$container->getReflectionClass($interface) || !$container->getReflectionClass($class))) { + continue; + } + if ($interface === $class || is_subclass_of($class, $interface)) { + $instanceofParent = clone $instanceofDef; + $instanceofParent->setAbstract(true)->setInheritTags(true)->setParent($parent); + $parent = 'instanceof.'.$interface.'.'.$id; + $container->setDefinition($parent, $instanceofParent); + + if (isset($instanceofParent->getChanges()['shared'])) { + $shared = $instanceofParent->isShared(); + } + } + } + + if ($instanceofParent) { + // cast Definition to ChildDefinition + $definition = serialize($definition); + $definition = substr_replace($definition, '53', 2, 2); + $definition = substr_replace($definition, 'Child', 44, 0); + $definition = unserialize($definition); + $definition->setInheritTags(true)->setParent($parent); + + if (null !== $shared && !isset($definition->getChanges()['shared'])) { + $definition->setShared($shared); + } + } + + return $definition; + } +} diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php index d1d6786145bad..2444e441ee53e 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php @@ -58,8 +58,13 @@ protected function processValue($value, $isRoot = false) return $this->bag->resolveValue($value); } if ($value instanceof Definition) { - $value->setClass($this->bag->resolveValue($value->getClass())); - $value->setFile($this->bag->resolveValue($value->getFile())); + $changes = $value->getChanges(); + if (isset($changes['class'])) { + $value->setClass($this->bag->resolveValue($value->getClass())); + } + if (isset($changes['file'])) { + $value->setFile($this->bag->resolveValue($value->getFile())); + } $value->setProperties($this->bag->resolveValue($value->getProperties())); $value->setMethodCalls($this->bag->resolveValue($value->getMethodCalls())); } diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php index 94671b80eb42f..6e79faba43f04 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php @@ -43,7 +43,9 @@ public function process(ContainerBuilder $container) $definition->setArguments($this->processArguments($definition->getArguments())); $definition->setMethodCalls($this->processArguments($definition->getMethodCalls())); $definition->setProperties($this->processArguments($definition->getProperties())); - $definition->setFactory($this->processFactory($definition->getFactory())); + if (isset($definition->getChanges()['factory'])) { + $definition->setFactory($this->processFactory($definition->getFactory())); + } } foreach ($container->getAliases() as $id => $alias) { diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ResolveTagsInheritancePass.php b/src/Symfony/Component/DependencyInjection/Compiler/ResolveTagsInheritancePass.php new file mode 100644 index 0000000000000..dbb0aab261650 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Compiler/ResolveTagsInheritancePass.php @@ -0,0 +1,52 @@ + + * + * 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\Exception\RuntimeException; + +/** + * Applies tags inheritance to definitions. + * + * @author Nicolas Grekas
+ */
+class ResolveTagsInheritancePass extends AbstractRecursivePass
+{
+ /**
+ * {@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 instanceof ChildDefinition) {
+ $this->processValue($parentDef);
+ }
+
+ foreach ($parentDef->getTags() as $k => $v) {
+ foreach ($v as $v) {
+ $value->addTag($k, $v);
+ }
+ }
+
+ return parent::processValue($value, $isRoot);
+ }
+}
diff --git a/src/Symfony/Component/DependencyInjection/Definition.php b/src/Symfony/Component/DependencyInjection/Definition.php
index e3c79c511aa7a..74922ea423ccf 100644
--- a/src/Symfony/Component/DependencyInjection/Definition.php
+++ b/src/Symfony/Component/DependencyInjection/Definition.php
@@ -39,8 +39,9 @@ class Definition
private $decoratedService;
private $autowired = false;
private $autowiringTypes = array();
+ private $changes = array();
- protected $arguments;
+ protected $arguments = array();
/**
* @param string|null $class The service class
@@ -48,10 +49,34 @@ class Definition
*/
public function __construct($class = null, array $arguments = array())
{
- $this->class = $class;
+ if (null !== $class) {
+ $this->setClass($class);
+ }
$this->arguments = $arguments;
}
+ /**
+ * Returns all changes tracked for the Definition object.
+ *
+ * @return array An array of changes for this Definition
+ */
+ public function getChanges()
+ {
+ return $this->changes;
+ }
+
+ /**
+ * Sets the tracked changes for the Definition object.
+ *
+ * @return $this
+ */
+ public function setChanges(array $changes)
+ {
+ $this->changes = $changes;
+
+ return $this;
+ }
+
/**
* Sets a factory.
*
@@ -61,6 +86,8 @@ public function __construct($class = null, array $arguments = array())
*/
public function setFactory($factory)
{
+ $this->changes['factory'] = true;
+
if (is_string($factory) && strpos($factory, '::') !== false) {
$factory = explode('::', $factory, 2);
}
@@ -97,6 +124,8 @@ public function setDecoratedService($id, $renamedId = null, $priority = 0)
throw new InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
}
+ $this->changes['decorated_service'] = true;
+
if (null === $id) {
$this->decoratedService = null;
} else {
@@ -125,6 +154,8 @@ public function getDecoratedService()
*/
public function setClass($class)
{
+ $this->changes['class'] = true;
+
$this->class = $class;
return $this;
@@ -448,6 +479,8 @@ public function clearTags()
*/
public function setFile($file)
{
+ $this->changes['file'] = true;
+
$this->file = $file;
return $this;
@@ -472,6 +505,8 @@ public function getFile()
*/
public function setShared($shared)
{
+ $this->changes['shared'] = true;
+
$this->shared = (bool) $shared;
return $this;
@@ -496,6 +531,8 @@ public function isShared()
*/
public function setPublic($boolean)
{
+ $this->changes['public'] = true;
+
$this->public = (bool) $boolean;
return $this;
@@ -520,6 +557,8 @@ public function isPublic()
*/
public function setLazy($lazy)
{
+ $this->changes['lazy'] = true;
+
$this->lazy = (bool) $lazy;
return $this;
@@ -612,6 +651,8 @@ public function setDeprecated($status = true, $template = null)
$this->deprecationTemplate = $template;
}
+ $this->changes['deprecated'] = true;
+
$this->deprecated = (bool) $status;
return $this;
@@ -649,6 +690,8 @@ public function getDeprecationMessage($id)
*/
public function setConfigurator($configurator)
{
+ $this->changes['configurator'] = true;
+
if (is_string($configurator) && strpos($configurator, '::') !== false) {
$configurator = explode('::', $configurator, 2);
}
@@ -709,6 +752,8 @@ public function isAutowired()
*/
public function setAutowired($autowired)
{
+ $this->changes['autowired'] = true;
+
$this->autowired = (bool) $autowired;
return $this;
diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
index 798b6b1adcde4..8ea27b4e1677d 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
@@ -222,12 +222,19 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults =
$defaults = array();
} else {
$definition = new Definition();
+
+ if (isset($defaults['public'])) {
+ $definition->setPublic($defaults['public']);
+ }
+ if (isset($defaults['autowire'])) {
+ $definition->setAutowired($defaults['autowire']);
+ }
+
+ $definition->setChanges(array());
}
if ($publicAttr = $service->getAttribute('public')) {
$definition->setPublic(XmlUtils::phpize($publicAttr));
- } elseif (isset($defaults['public'])) {
- $definition->setPublic($defaults['public']);
}
foreach (array('class', 'shared', 'synthetic', 'lazy', 'abstract') as $key) {
@@ -239,8 +246,6 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults =
if ($value = $service->getAttribute('autowire')) {
$definition->setAutowired(XmlUtils::phpize($value));
- } elseif (isset($defaults['autowire'])) {
- $definition->setAutowired($defaults['autowire']);
}
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 7c7550e6c982b..52e91883eb3c8 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
@@ -81,10 +81,6 @@ class YamlFileLoader extends FileLoader
'shared' => 'shared',
'lazy' => 'lazy',
'public' => 'public',
- 'abstract' => 'abstract',
- 'deprecated' => 'deprecated',
- 'factory' => 'factory',
- 'arguments' => 'arguments',
'properties' => 'properties',
'configurator' => 'configurator',
'calls' => 'calls',
@@ -366,6 +362,15 @@ private function parseDefinition($id, $service, $file, array $defaults)
$defaults = array();
} else {
$definition = new Definition();
+
+ if (isset($defaults['public'])) {
+ $definition->setPublic($defaults['public']);
+ }
+ if (isset($defaults['autowire'])) {
+ $definition->setAutowired($defaults['autowire']);
+ }
+
+ $definition->setChanges(array());
}
if (isset($service['class'])) {
@@ -384,9 +389,8 @@ private function parseDefinition($id, $service, $file, array $defaults)
$definition->setLazy($service['lazy']);
}
- $public = isset($service['public']) ? $service['public'] : (isset($defaults['public']) ? $defaults['public'] : null);
- if (null !== $public) {
- $definition->setPublic($public);
+ if (isset($service['public'])) {
+ $definition->setPublic($service['public']);
}
if (isset($service['abstract'])) {
@@ -484,9 +488,8 @@ private function parseDefinition($id, $service, $file, array $defaults)
$definition->setDecoratedService($service['decorates'], $renameId, $priority);
}
- $autowire = isset($service['autowire']) ? $service['autowire'] : (isset($defaults['autowire']) ? $defaults['autowire'] : null);
- if (null !== $autowire) {
- $definition->setAutowired($autowire);
+ if (isset($service['autowire'])) {
+ $definition->setAutowired($service['autowire']);
}
if (isset($service['autowiring_types'])) {
diff --git a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
index ebbcf00ef487a..79a9ad4637cf6 100644
--- a/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
+++ b/src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
@@ -136,10 +136,7 @@