Skip to content

Commit 913153e

Browse files
Merge branch '6.4' into 7.0
* 6.4: [Runtime][ErrorHandler] Don't mess with ini_set('assert.warning') [DependencyInjection] Fix fetching lazy non-shared services multiple times [FrameworkBundle] Run the `ResolveFactoryClassPass` when `lint:container` builds the container from a dump
2 parents 19b0f11 + e2d6388 commit 913153e

File tree

4 files changed

+237
-1
lines changed

4 files changed

+237
-1
lines changed

Dumper/PhpDumper.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,6 +917,8 @@ protected static function {$methodName}(\$container$lazyInitialization)
917917

918918
if ($asFile) {
919919
$code .= "self::do(...);\n\n";
920+
} elseif ($definition->isPublic()) {
921+
$code .= sprintf("fn () => self::%s(\$container);\n\n", $methodName);
920922
} else {
921923
$code .= sprintf("self::%s(...);\n\n", $methodName);
922924
}

Tests/Dumper/PhpDumperTest.php

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,42 @@ public function testInlinedDefinitionReferencingServiceContainer()
765765
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services13.php', $dumper->dump(), '->dump() dumps inline definitions which reference service_container');
766766
}
767767

768+
public function testNonSharedLazy()
769+
{
770+
$container = new ContainerBuilder();
771+
772+
$container
773+
->register('foo', Foo::class)
774+
->setFile(realpath(self::$fixturesPath.'/includes/foo_lazy.php'))
775+
->setShared(false)
776+
->setLazy(true)
777+
->setPublic(true);
778+
779+
$container->compile();
780+
$dumper = new PhpDumper($container);
781+
$dump = $dumper->dump([
782+
'class' => 'Symfony_DI_PhpDumper_Service_Non_Shared_Lazy',
783+
'file' => __DIR__,
784+
'inline_factories' => false,
785+
'inline_class_loader' => false,
786+
]);
787+
$this->assertStringEqualsFile(
788+
self::$fixturesPath.'/php/services_non_shared_lazy_public.php',
789+
'\\' === \DIRECTORY_SEPARATOR ? str_replace("'.\\DIRECTORY_SEPARATOR.'", '/', $dump) : $dump
790+
);
791+
eval('?>'.$dump);
792+
793+
$container = new \Symfony_DI_PhpDumper_Service_Non_Shared_Lazy();
794+
795+
$foo1 = $container->get('foo');
796+
$this->assertTrue($foo1->resetLazyObject());
797+
798+
$foo2 = $container->get('foo');
799+
$this->assertTrue($foo2->resetLazyObject());
800+
801+
$this->assertNotSame($foo1, $foo2);
802+
}
803+
768804
/**
769805
* @testWith [false]
770806
* [true]
@@ -773,7 +809,7 @@ public function testNonSharedLazyDefinitionReferences(bool $asGhostObject)
773809
{
774810
$container = new ContainerBuilder();
775811
$container->register('foo', 'stdClass')->setShared(false)->setLazy(true);
776-
$container->register('bar', 'stdClass')->addArgument(new Reference('foo', ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE, false))->setPublic(true);
812+
$container->register('bar', 'stdClass')->addArgument(new Reference('foo', ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE))->setPublic(true);
777813
$container->compile();
778814

779815
$dumper = new PhpDumper($container);
@@ -1530,6 +1566,37 @@ public function testLazyWither()
15301566
$this->assertTrue($wither->resetLazyObject());
15311567
}
15321568

1569+
public function testLazyWitherNonShared()
1570+
{
1571+
$container = new ContainerBuilder();
1572+
$container->register(Foo::class);
1573+
1574+
$container
1575+
->register('wither', Wither::class)
1576+
->setShared(false)
1577+
->setLazy(true)
1578+
->setPublic(true)
1579+
->setAutowired(true);
1580+
1581+
$container->compile();
1582+
$dumper = new PhpDumper($container);
1583+
$dump = $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Service_Wither_Lazy_Non_Shared']);
1584+
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_wither_lazy_non_shared.php', $dump);
1585+
eval('?>'.$dump);
1586+
1587+
$container = new \Symfony_DI_PhpDumper_Service_Wither_Lazy_Non_Shared();
1588+
1589+
$wither1 = $container->get('wither');
1590+
$this->assertInstanceOf(Foo::class, $wither1->foo);
1591+
$this->assertTrue($wither1->resetLazyObject());
1592+
1593+
$wither2 = $container->get('wither');
1594+
$this->assertInstanceOf(Foo::class, $wither2->foo);
1595+
$this->assertTrue($wither2->resetLazyObject());
1596+
1597+
$this->assertNotSame($wither1, $wither2);
1598+
}
1599+
15331600
public function testWitherWithStaticReturnType()
15341601
{
15351602
$container = new ContainerBuilder();
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
4+
use Symfony\Component\DependencyInjection\ContainerInterface;
5+
use Symfony\Component\DependencyInjection\Container;
6+
use Symfony\Component\DependencyInjection\Exception\LogicException;
7+
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
8+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
9+
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
10+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
11+
12+
/**
13+
* @internal This class has been auto-generated by the Symfony Dependency Injection Component.
14+
*/
15+
class Symfony_DI_PhpDumper_Service_Non_Shared_Lazy extends Container
16+
{
17+
protected $parameters = [];
18+
19+
public function __construct()
20+
{
21+
$this->services = $this->privates = [];
22+
$this->methodMap = [
23+
'foo' => 'getFooService',
24+
];
25+
26+
$this->aliases = [];
27+
}
28+
29+
public function compile(): void
30+
{
31+
throw new LogicException('You cannot compile a dumped container that was already compiled.');
32+
}
33+
34+
public function isCompiled(): bool
35+
{
36+
return true;
37+
}
38+
39+
protected function createProxy($class, \Closure $factory)
40+
{
41+
return $factory();
42+
}
43+
44+
/**
45+
* Gets the public 'foo' service.
46+
*
47+
* @return \Symfony\Component\DependencyInjection\Tests\Compiler\Foo
48+
*/
49+
protected static function getFooService($container, $lazyLoad = true)
50+
{
51+
$container->factories['foo'] ??= fn () => self::getFooService($container);
52+
53+
if (true === $lazyLoad) {
54+
return $container->createProxy('FooGhost80f7cfc', static fn () => \FooGhost80f7cfc::createLazyGhost(static fn ($proxy) => self::getFooService($container, $proxy)));
55+
}
56+
57+
static $include = true;
58+
59+
if ($include) {
60+
include_once __DIR__.'/Fixtures/includes/foo_lazy.php';
61+
62+
$include = false;
63+
}
64+
65+
return $lazyLoad;
66+
}
67+
}
68+
69+
class FooGhost80f7cfc extends \Symfony\Component\DependencyInjection\Tests\Compiler\Foo implements \Symfony\Component\VarExporter\LazyObjectInterface
70+
{
71+
use \Symfony\Component\VarExporter\LazyGhostTrait;
72+
73+
private const LAZY_OBJECT_PROPERTY_SCOPES = [];
74+
}
75+
76+
// Help opcache.preload discover always-needed symbols
77+
class_exists(\Symfony\Component\VarExporter\Internal\Hydrator::class);
78+
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectRegistry::class);
79+
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class);
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
4+
use Symfony\Component\DependencyInjection\ContainerInterface;
5+
use Symfony\Component\DependencyInjection\Container;
6+
use Symfony\Component\DependencyInjection\Exception\LogicException;
7+
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
8+
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
9+
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
10+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
11+
12+
/**
13+
* @internal This class has been auto-generated by the Symfony Dependency Injection Component.
14+
*/
15+
class Symfony_DI_PhpDumper_Service_Wither_Lazy_Non_Shared extends Container
16+
{
17+
protected $parameters = [];
18+
19+
public function __construct()
20+
{
21+
$this->services = $this->privates = [];
22+
$this->methodMap = [
23+
'wither' => 'getWitherService',
24+
];
25+
26+
$this->aliases = [];
27+
}
28+
29+
public function compile(): void
30+
{
31+
throw new LogicException('You cannot compile a dumped container that was already compiled.');
32+
}
33+
34+
public function isCompiled(): bool
35+
{
36+
return true;
37+
}
38+
39+
public function getRemovedIds(): array
40+
{
41+
return [
42+
'Symfony\\Component\\DependencyInjection\\Tests\\Compiler\\Foo' => true,
43+
];
44+
}
45+
46+
protected function createProxy($class, \Closure $factory)
47+
{
48+
return $factory();
49+
}
50+
51+
/**
52+
* Gets the public 'wither' autowired service.
53+
*
54+
* @return \Symfony\Component\DependencyInjection\Tests\Compiler\Wither
55+
*/
56+
protected static function getWitherService($container, $lazyLoad = true)
57+
{
58+
$container->factories['wither'] ??= fn () => self::getWitherService($container);
59+
60+
if (true === $lazyLoad) {
61+
return $container->createProxy('WitherProxyDd381be', static fn () => \WitherProxyDd381be::createLazyProxy(static fn () => self::getWitherService($container, false)));
62+
}
63+
64+
$instance = new \Symfony\Component\DependencyInjection\Tests\Compiler\Wither();
65+
66+
$a = ($container->privates['Symfony\\Component\\DependencyInjection\\Tests\\Compiler\\Foo'] ??= new \Symfony\Component\DependencyInjection\Tests\Compiler\Foo());
67+
68+
$instance = $instance->withFoo1($a);
69+
$instance = $instance->withFoo2($a);
70+
$instance->setFoo($a);
71+
72+
return $instance;
73+
}
74+
}
75+
76+
class WitherProxyDd381be extends \Symfony\Component\DependencyInjection\Tests\Compiler\Wither implements \Symfony\Component\VarExporter\LazyObjectInterface
77+
{
78+
use \Symfony\Component\VarExporter\LazyProxyTrait;
79+
80+
private const LAZY_OBJECT_PROPERTY_SCOPES = [
81+
'foo' => [parent::class, 'foo', null],
82+
];
83+
}
84+
85+
// Help opcache.preload discover always-needed symbols
86+
class_exists(\Symfony\Component\VarExporter\Internal\Hydrator::class);
87+
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectRegistry::class);
88+
class_exists(\Symfony\Component\VarExporter\Internal\LazyObjectState::class);

0 commit comments

Comments
 (0)