10000 [DI] enable improved syntax for defining method calls in Yaml · dontub/symfony@cdc7446 · GitHub
[go: up one dir, main page]

Skip to content

Commit cdc7446

Browse files
[DI] enable improved syntax for defining method calls in Yaml
1 parent bf406da commit cdc7446

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ CHANGELOG
1212
* added support for binding iterable and tagged services
1313
* made singly-implemented interfaces detection be scoped by file
1414
* added ability to define a static priority method for tagged service
15+
* added support for improved syntax to define method calls in Yaml
1516

1617
4.3.0
1718
-----

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

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -459,20 +459,48 @@ private function parseDefinition(string $id, $service, string $file, array $defa
459459
throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
460460
}
461461

462-
foreach ($service['calls'] as $call) {
462+
foreach ($service['calls'] as $k => $call) {
463+
if (!\is_array($call) && (!\is_string($k) || !$call instanceof TaggedValue)) {
464+
throw new InvalidArgumentException(sprintf('Invalid method call for service "%s": expected map or array, %s given in %s.', $id, $call instanceof TaggedValue ? '!'.$call->getTag() : \gettype($call), $file));
465+
}
466+
467+
if (\is_string($k)) {
468+
throw new InvalidArgumentException(sprintf('Invalid method call for service "%s", did you forgot a leading dash before "%s: ..." in %s?', $id, $k, $file));
469+
}
470+
463471
if (isset($call['method'])) {
464472
$method = $call['method'];
465-
$args = isset($call['arguments']) ? $this->resolveServices($call['arguments'], $file) : [];
473+
$args = $call['arguments'] ?? [];
466474
$returnsClone = $call['returns_clone'] ?? false;
467475
} else {
468-
$method = $call[0];
469-
$args = isset($call[1]) ? $this->resolveServices($call[1], $file) : [];
470-
$returnsClone = $call[2] ?? false;
476+
if (1 === \count($call) && \is_string(key($call))) {
477+
$method = key($call);
478+
$args = $call[$method];
479+
480+
if ($args instanceof TaggedValue) {
481+
if ('returns_clone' !== $args->getTag()) {
482+
throw new InvalidArgumentException(sprintf('Unsupported tag "!%s", did you mean "!returns_clone" for service "%s" in %s?', $args->getTag(), $id, $file));
483+
}
484+
485+
$returnsClone = true;
486+
$args = $args->getValue();
487+
} else {
488+
$returnsClone = false;
489+
}
490+
} elseif (empty($call[0])) {
491+
throw new InvalidArgumentException(sprintf('Invalid call for service "%s": the method must be defined as the first index of an array or as the only key of a map in %s.', $id, $file));
492+
} else {
493+
$method = $call[0];
494+
$args = $call[1] ?? [];
495+
$returnsClone = $call[2] ?? false;
496+
}
471497
}
472498

473499
if (!\is_array($args)) {
474500
throw new InvalidArgumentException(sprintf('The second parameter for function call "%s" must be an array of its arguments for service "%s" in %s. Check your YAML syntax.', $method, $id, $file));
475501
}
502+
503+
$args = $this->resolveServices($args, $file);
476504
$definition->addMethodCall($method, $args, $returnsClone);
477505
}
478506
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
services:
2+
foo:
3+
calls:
4+
- foo: [1, 2, 3]
5+
- bar: !returns_clone [1, 2, 3]

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,4 +900,19 @@ public function testNotSinglyImplementedInterfacesInMultipleResourcesWithPreviou
900900

901901
$this->assertSame(Prototype\SinglyImplementedInterface\Adapter\Adapter::class, (string) $alias);
902902
}
903+
904+
public function testAlternativeMethodCalls()
905+
{
906+
$container = new ContainerBuilder();
907+
908+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
909+
$loader->load('alt_call.yaml');
910+
911+
$expected = [
912+
['foo', [1, 2, 3]],
913+
['bar', [1, 2, 3], true],
914+
];
915+
916+
$this->assertSame($expected, $container->getDefinition('foo')->getMethodCalls());
917+
}
903918
}

0 commit comments

Comments
 (0)
0