Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0f5a1c8

Browse filesBrowse files
[DI] Add support for "wither" methods - for greater immutable services
1 parent b9b8f9d commit 0f5a1c8
Copy full SHA for 0f5a1c8

File tree

Expand file treeCollapse file tree

16 files changed

+189
-12
lines changed
Filter options
Expand file treeCollapse file tree

16 files changed

+189
-12
lines changed

‎src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/XmlDescriptor.php
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,9 @@ private function getContainerDefinitionDocument(Definition $definition, string $
343343
foreach ($calls as $callData) {
344344
$callsXML->appendChild($callXML = $dom->createElement('call'));
345345
$callXML->setAttribute('method', $callData[0]);
346+
if ($callData[2] ?? false) {
347+
$callXML->setAttribute('use-result', 'true');
348+
}
346349
}
347350
}
348351

‎src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php
+11-1Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,21 @@ protected function processValue($value, $isRoot = false)
140140
$this->byConstructor = true;
141141
$this->processValue($value->getFactory());
142142
$this->processValue($value->getArguments());
143+
144+
// "wither" calls are part of the constructor-instantiation graph
145+
$setterCalls = [];
146+
foreach ($value->getMethodCalls() as $call) {
147+
if ($call[2] ?? false) {
148+
$this->processValue($call);
149+
} else {
150+
$setterCalls[] = $call;
151+
}
152+
}
143153
$this->byConstructor = $byConstructor;
144154

145155
if (!$this->onlyConstructorArguments) {
146156
$this->processValue($value->getProperties());
147-
$this->processValue($value->getMethodCalls());
157+
$this->processValue($setterCalls);
148158
$this->processValue($value->getConfigurator());
149159
}
150160
$this->lazy = $lazy;

‎src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/AutowireRequiredMethodsPass.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ protected function processValue($value, $isRoot = false)
5050
while (true) {
5151
if (false !== $doc = $r->getDocComment()) {
5252
if (false !== stripos($doc, '@required') && preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@required(?:\s|\*/$)#i', $doc)) {
53-
$value->addMethodCall($reflectionMethod->name);
53+
$value->addMethodCall($reflectionMethod->name, [], preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@return\s++static[\s\*]#i', $doc));
5454
break;
5555
}
5656
if (false === stripos($doc, '@inheritdoc') || !preg_match('#(?:^/\*\*|\n\s*+\*)\s*+(?:\{@inheritdoc\}|@inheritdoc)(?:\s|\*/$)#i', $doc)) {

‎src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+6-4Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ private function createService(Definition $definition, array &$inlineServices, $
11501150
}
11511151

11521152
foreach ($definition->getMethodCalls() as $call) {
1153-
$this->callMethod($service, $call, $inlineServices);
1153+
$service = $this->callMethod($service, $call, $inlineServices);
11541154
}
11551155

11561156
if ($callable = $definition->getConfigurator()) {
@@ -1568,16 +1568,18 @@ private function callMethod($service, $call, array &$inlineServices)
15681568
{
15691569
foreach (self::getServiceConditionals($call[1]) as $s) {
15701570
if (!$this->has($s)) {
1571-
return;
1571+
return $service;
15721572
}
15731573
}
15741574
foreach (self::getInitializedConditionals($call[1]) as $s) {
15751575
if (!$this->doGet($s, ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE, $inlineServices)) {
1576-
return;
1576+
return $service;
15771577
}
15781578
}
15791579

1580-
$service->{$call[0]}(...$this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlineServices));
1580+
$result = $service->{$call[0]}(...$this->doResolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1])), $inlineServices));
1581+
1582+
return empty($call[2]) ? $service : $result;
15811583
}
15821584

15831585
/**

‎src/Symfony/Component/DependencyInjection/Definition.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Definition.php
+4-3Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ public function setMethodCalls(array $calls = [])
330330
{
331331
$this->calls = [];
332332
foreach ($calls as $call) {
333-
$this->addMethodCall($call[0], $call[1]);
333+
$this->addMethodCall($call[0], $call[1], $call[2] ?? false);
334334
}
335335

336336
return $this;
@@ -341,17 +341,18 @@ public function setMethodCalls(array $calls = [])
341341
*
342342
* @param string $method The method name to call
343343
* @param array $arguments An array of arguments to pass to the method call
344+
* @param bool $useResult Whether the call returns the service instance or not
344345
*
345346
* @return $this
346347
*
347348
* @throws InvalidArgumentException on empty $method param
348349
*/
349-
public function addMethodCall($method, array $arguments = [])
350+
public function addMethodCall($method, array $arguments = []/*, bool $useResult = false*/)
350351
{
351352
if (empty($method)) {
352353
throw new InvalidArgumentException('Method name cannot be empty.');
353354
}
354-
$this->calls[] = [$method, $arguments];
355+
$this->calls[] = 2 < \func_num_args() && \func_get_arg(2) ? [$method, $arguments, true] : [$method, $arguments];
355356

356357
return $this;
357358
}

‎src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+12-1Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ private function addServiceMethodCalls(Definition $definition, string $variableN
572572
$arguments[] = $this->dumpValue($value);
573573
}
574574

575-
$calls .= $this->wrapServiceConditionals($call[1], sprintf(" \$%s->%s(%s);\n", $variableName, $call[0], implode(', ', $arguments)));
575+
$calls .= $this->wrapServiceConditionals($call[1], sprintf(" %s\$%s->%s(%s);\n", empty($call[2]) ? '' : "\${$variableName} = ", $variableName, $call[0], implode(', ', $arguments)));
576576
}
577577

578578
return $calls;
@@ -820,6 +820,17 @@ private function addInlineService(string $id, Definition $definition, Definition
820820

821821
if ($isRootInstance && !$isSimpleInstance) {
822822
$code .= "\n return \$instance;\n";
823+
824+
foreach ($definition->getMethodCalls() as $call) {
825+
if (!($call[2] ?? false)) {
826+
continue;
827+
}
828+
829+
if (!$this->getProxyDumper()->isProxyCandidate($definition) && $definition->isShared() && !isset($this->singleUsePrivateIds[$id])) {
830+
$code = substr_replace($code, sprintf('$this->%s[\'%s\'] = ', $definition->isPublic() ? 'services' : 'privates', $id), -11, 0);
831+
break;
832+
}
833+
}
823834
}
824835

825836
return $code;

‎src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ private function addMethodCalls(array $methodcalls, \DOMElement $parent)
8484
if (\count($methodcall[1])) {
8585
$this->convertParameters($methodcall[1], 'argument', $call);
8686
}
87+
if ($methodcall[2] ?? false) {
88+
$call->setAttribute('use-result', 'true');
89+
}
8790
$parent->appendChild($call);
8891
}
8992
}

‎src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults)
337337
}
338338

339339
foreach ($this->getChildren($service, 'call') as $call) {
340-
$definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument', $file));
340+
$definition->addMethodCall($call->getAttribute('method'), $this->getArgumentsAsPhp($call, 'argument', $file), $call->getAttribute('use-result'));
341341
}
342342

343343
$tags = $this->getChildren($service, 'tag');

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ private function parseDefinition($id, $service, $file, array $defaults)
471471
if (!\is_array($args)) {
472472
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));
473473
}
474-
$definition->addMethodCall($method, $args);
474+
$definition->addMethodCall($method, $args, $call['use_result'] ?? false);
475475
}
476476
}
477477

‎src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@
241241
<xsd:element name="argument" type="argument" maxOccurs="unbounded" />
242242
</xsd:choice>
243243
<xsd:attribute name="method" type="xsd:string" />
244+
<xsd:attribute name="use-result" type="boolean" />
244245
</xsd:complexType>
245246

246247
<xsd:simpleType name="parameter_type">

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.