Skip to content

Promoted readonly properties are not respected #737

@bobvandevijver

Description

@bobvandevijver

When using a promoted readonly only property in a class, this library will generate code that tries to change the readonly property and therefor breaking execution. Consider the following class (all have been stripped to only show the constructor):

class SystemNotificationService extends AbstractCacheableService
{
  public function __construct(
      private readonly SystemNotificationRepository $systemNotificationRepository,
      private readonly SerializerInterface $serializer,
      Features $features,
      string $kernelEnvironment,
      string $commitHash,
      string $httpHost,
      string $cacheDir)
  {
    parent::__construct($features, $kernelEnvironment, $commitHash, $httpHost, $cacheDir);
  }
}
abstract class AbstractCacheableService
{
  public function __construct(
      protected readonly Features $features,
      string $kernelEnvironment,
      string $commitHash,
      string $httpHost,
      private readonly string $cacheDir)
  {
  }
}

will generate the following proxy:

class SystemNotificationService_6ddbdeb extends \App\Service\SystemNotificationService implements \ProxyManager\Proxy\VirtualProxyInterface
{
    public function __construct(private \JMS\Serializer\SerializerInterface $serializer, \App\Features $features)
    {
        static $reflection;

        if (! $this->valueHolder06ae0) {
            $reflection = $reflection ?? new \ReflectionClass('App\\Service\\SystemNotificationService');
            $this->valueHolder06ae0 = $reflection->newInstanceWithoutConstructor();
        unset($this->features);

        \Closure::bind(function (\App\Service\SystemNotificationService $instance) {
            unset($instance->systemNotificationRepository, $instance->serializer);
        }, $this, 'App\\Service\\SystemNotificationService')->__invoke($this);

        \Closure::bind(function (\App\Service\AbstractCacheableService $instance) {
            unset($instance->cache, $instance->cacheHash, $instance->clearedTags, $instance->clearedKeys, $instance->cacheDir);
        }, $this, 'App\\Service\\AbstractCacheableService')->__invoke($this);

        }

        $this->valueHolder06ae0->__construct($systemNotificationRepository, $serializer, $features, $kernelEnvironment, $commitHash, $httpHost, $cacheDir);
    }
}

and thus throw Cannot unset readonly property App\Service\AbstractCacheableService::$features from scope ContainerXH6sJpc\SystemNotificationService_6ddbdeb, caused by the unset($instance->features).

Note that the same will also happen with the systemNotificationRepository and serializer properties (unset($instance->systemNotificationRepository, $instance->serializer);).

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions