Skip to content

Commit

Permalink
[DependencyInjection] fix unable to make lazy service from readonly c…
Browse files Browse the repository at this point in the history
…lass
  • Loading branch information
kor3k authored and nicolas-grekas committed Feb 9, 2024
1 parent da332ce commit 774d507
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 2 deletions.
4 changes: 3 additions & 1 deletion Dumper/PhpDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,9 @@ private function generateProxyClasses(): array
$proxyCode = substr(self::stripComments($proxyCode), 5);
}

$proxyClass = explode(' ', $this->inlineRequires ? substr($proxyCode, \strlen($code)) : $proxyCode, 3)[1];
$proxyClass = $this->inlineRequires ? substr($proxyCode, \strlen($code)) : $proxyCode;
$i = strpos($proxyClass, 'class');
$proxyClass = substr($proxyClass, 6 + $i, strpos($proxyClass, ' ', 7 + $i) - $i - 6);

if ($this->asFiles || $this->namespace) {
$proxyCode .= "\nif (!\\class_exists('$proxyClass', false)) {\n \\class_alias(__NAMESPACE__.'\\\\$proxyClass', '$proxyClass', false);\n}\n";
Expand Down
2 changes: 1 addition & 1 deletion LazyProxy/PhpDumper/LazyServiceDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public function getProxyCode(Definition $definition, ?string $id = null): string

if ($asGhostObject) {
try {
return 'class '.$proxyClass.ProxyHelper::generateLazyGhost($class);
return (\PHP_VERSION_ID >= 80200 && $class?->isReadOnly() ? 'readonly ' : '').'class '.$proxyClass.ProxyHelper::generateLazyGhost($class);
} catch (LogicException $e) {
throw new InvalidArgumentException(sprintf('Cannot generate lazy ghost for service "%s".', $id ?? $definition->getClass()), 0, $e);
}
Expand Down
20 changes: 20 additions & 0 deletions Tests/Fixtures/ReadonlyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\DependencyInjection\Tests\Fixtures;

readonly class ReadonlyTest
{
public function say(): string
{
return 'hello';
}
}
13 changes: 13 additions & 0 deletions Tests/LazyProxy/PhpDumper/LazyServiceDumperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\LazyServiceDumper;
use Symfony\Component\DependencyInjection\Tests\Fixtures\ReadonlyTest;

class LazyServiceDumperTest extends TestCase
{
Expand Down Expand Up @@ -52,6 +53,18 @@ public function testInvalidClass()
$this->expectExceptionMessage('Invalid "proxy" tag for service "stdClass": class "stdClass" doesn\'t implement "Psr\Container\ContainerInterface".');
$dumper->getProxyCode($definition);
}

/**
* @requires PHP 8.2
*/
public function testReadonlyClass()
{
$dumper = new LazyServiceDumper();
$definition = (new Definition(ReadonlyTest::class))->setLazy(true);

$this->assertTrue($dumper->isProxyCandidate($definition));
$this->assertStringContainsString('readonly class ReadonlyTestGhost', $dumper->getProxyCode($definition));
}
}

final class TestContainer implements ContainerInterface
Expand Down

0 comments on commit 774d507

Please sign in to comment.