10000 Fixes issues #27828 and #28326 · symfony/symfony@5c037b9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5c037b9

Browse files
Fixes issues #27828 and #28326
1 parent b6b5976 commit 5c037b9

File tree

9 files changed

+142
-5
lines changed

9 files changed

+142
-5
lines changed

src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,41 @@
1616
*/
1717
final class BoundArgument implements ArgumentInterface
1818
{
19+
const SERVICE_BIND = 0;
20+
const DEFAULT_BIND = 1;
21+
const INSTANCE_BIND = 2;
22+
23+
const MESSAGES = [
24+
1 => 'under "_defaults"',
25+
2 => 'under "_instanceof"',
26+
];
27+
1928
private static $sequence = 0;
2029

2130
private $value;
2231
private $identifier;
2332
private $used;
33+
private $type;
34+
private $file;
2435

25-
public function __construct($value)
36+
public function __construct($value, $type = 0, $file = null)
2637
{
2738
$this->value = $value;
2839
$this->identifier = ++self::$sequence;
40+
$this->type = (int) $type;
41+
$this->file = (string) $file;
2942
}
3043

3144
/**
3245
* {@inheritdoc}
3346
*/
3447
public function getValues()
3548
{
49+
<<<<<<< HEAD
3650
return [$this->value, $this->identifier, $this->used];
51+
=======
52+
return [$this->value, $this->identifier, $this->used, $this->type, $this->file];
53+
>>>>>>> Fixes issues #27828 and #28326
3754
}
3855

3956
/**

src/Symfony/Component/DependencyInjection/Compiler/ResolveBindingsPass.php

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,34 @@ class ResolveBindingsPass extends AbstractRecursivePass
3434
*/
3535
public function process(ContainerBuilder $container)
3636
{
37+
foreach ($container->getBindings() as $definition) {
38+
foreach ($definition as $argument => $values) {
39+
if (1 < \count($values)) {
40+
foreach (\array_slice(array_keys($values), 0, -1) as $value) {
41+
$this->usedBindings[$value] = true;
42+
}
43+
}
44+
}
45+
}
46+
3747
try {
3848
parent::process($container);
3949

40-
foreach ($this->unusedBindings as list($key, $serviceId)) {
41-
$message = sprintf('Unused binding "%s" in service "%s".', $key, $serviceId);
50+
foreach ($this->unusedBindings as list($key, $serviceId, $type, $file)) {
51+
$message = sprintf('You have a "bind" configured for an argument named "%s" ', $key);
52+
53+
if ($type) {
54+
$message .= BoundArgument::MESSAGES[$type];
55+
} else {
56+
$message .= sprintf('in service "%s"', $serviceId);
57+
}
58+
59+
if ($file) {
60+
$message .= sprintf(' in file "%s"', $file);
61+
}
62+
63+
$message .= '. But, this argument was not found in any of the services it was applied to. It may be unused and can be removed, or it may have a typo.';
64+
4265
if ($this->errorMessages) {
4366
$message .= sprintf("\nCould be related to%s:", 1 < \count($this->errorMessages) ? ' one of' : '');
4467
}
@@ -75,12 +98,16 @@ protected function processValue($value, $isRoot = false)
7598
}
7699

77100
foreach ($bindings as $key => $binding) {
78-
list($bindingValue, $bindingId, $used) = $binding->getValues();
101+
list($bindingValue, $bindingId, $used, $bindingType, $file) = $binding->getValues();
79102
if ($used) {
80103
$this->usedBindings[$bindingId] = true;
81104
unset($this->unusedBindings[$bindingId]);
82105
} elseif (!isset($this->usedBindings[$bindingId])) {
106+< F438 /span>
<<<<<<< HEAD
83107
$this->unusedBindings[$bindingId] = [$key, $this->currentId];
108+
=======
109+
$this->unusedBindings[$bindingId] = [$key, $this->currentId, $bindingType, $file];
110+
>>>>>>> Fixes issues #27828 and #28326
84111
}
85112

86113
if (isset($key[0]) && '$' === $key[0]) {

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
123123

124124
private $removedIds = [];
125125

126+
<<<<<<< HEAD
127+
=======
128+
/**
129+
* @var bool[][][] a map of values bound to arguments in definitions
130+
*/
131+
private $bindings = [];
132+
133+
>>>>>>> Fixes issues #27828 and #28326
126134
private static $internalTypes = [
127135
'int' => true,
128136
'float' => true,
@@ -1021,6 +1029,14 @@ public function setDefinition($id, Definition $definition)
10211029

10221030
unset($this->aliasDefinitions[$id], $this->removedIds[$id]);
10231031

1032+
$bindings = $definition->getBindings();
1033+
if (!empty($bindings)) {
1034+
foreach ($bindings as $argument => $binding) {
1035+
list(, $identifier) = $binding->getValues();
1036+
$this->bindings[$id][$argument][$identifier] = true;
1037+
}
1038+
}
1039+
10241040
return $this->definitions[$id] = $definition;
10251041
}
10261042

@@ -1656,4 +1672,9 @@ private function inVendors($path)
16561672

16571673
return false;
16581674
}
1675+
1676+
public function getBindings(): array
1677+
{
1678+
return $this->bindings;
1679+
}
16591680
}

src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,9 @@ private function parseDefaults(array &$content, $file)
299299
throw new InvalidArgumentException(sprintf('Parameter "bind" in "_defaults" must be an array in %s. Check your YAML syntax.', $file));
300300
}
301301

302-
$defaults['bind'] = array_map(function ($v) { return new BoundArgument($v); }, $this->resolveServices($defaults['bind'], $file));
302+
foreach ($this->resolveServices($defaults['bind'], $file) as $argument => $value) {
303+
$defaults['bind'][$argument] = new BoundArgument($value, BoundArgument::DEFAULT_BIND, $file);
304+
}
303305
}
304306

305307
return $defaults;
@@ -558,6 +560,12 @@ private function parseDefinition($id, $service, $file, array $defaults)
558560
}
559561

560562
$bindings = array_merge($bindings, $this->resolveServices($service['bind'], $file));
563+
564+
$bindingType = $this->isLoadingInstanceof ? BoundArgument::INSTANCE_BIND : BoundArgument::SERVICE_BIND;
565+
566+
foreach ($bindings as $argument => $value) {
567+
$bindings[$argument] = new BoundArgument($value, $bindingType, $file);
568+
}
561569
}
562570

563571
$definition->setBindings($bindings);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Symfony\Component\DependencyInjection\Tests\Fixtures;
4+
5+
class Foo
6+
{
7+
public function __construct($abc)
8+
{
9+
}
10+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
services:
2+
_defaults:
3+
bind:
4+
$quz: quzFirstValue
5+
$abc: abcFirstValue
6+
7+
bar:
8+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Bar
9+
10+
factory:
11+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummy
12+
13+
foo:
14+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Foo
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
services:
2+
_defaults:
3+
bind:
4+
$abc: abcSecondValue
5+
6+
foo:
7+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Foo
8+
9+
factory:
10+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\FactoryDummy
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
services:
2+
_defaults:
3+
bind:
4+
$abc: abcThirdValue
5+
6+
foo:
7+
class: Symfony\Component\DependencyInjection\Tests\Fixtures\Foo
8+
bind:

src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Config\Resource\FileResource;
1818
use Symfony\Component\Config\Resource\GlobResource;
1919
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
20+
use Symfony\Component\DependencyInjection\Compiler\ResolveBindingsPass;
2021
use Symfony\Component\DependencyInjection\ContainerBuilder;
2122
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
2223
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
@@ -731,5 +732,26 @@ public function testBindings()
731732
'$quz' => 'quz',
732733
'$factory' => 'factory',
733734
], array_map(function ($v) { return $v->getValues()[0]; }, $definition->getBindings()));
735+
<<<<<<< HEAD
736+
=======
737+
}
738+
739+
/**
740+
* The pass may throw an exception, which will cause the test to fail.
741+
*/
742+
public function testOverriddenDefaultsBindings()
743+
{
744+
$container = new ContainerBuilder();
745+
746+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
747+
$loader->load('defaults_bindings.yml');
748+
$loader->load('defaults_bindings2.yml');
749+
$loader->load('defaults_bindings3.yml');
750+
751+
$pass = new ResolveBindingsPass();
752+
$pass->process($container);
753+
754+
$this->assertTrue(true);
755+
>>>>>>> Fixes issues #27828 and #28326
734756
}
735757
}

0 commit comments

Comments
 (0)
0