Skip to content

Conversation

@guanguans
Copy link
Contributor

issue: RectorConfig is injected via constructor, it is a new RectorConfig empty container instance.

use PhpParser\Node;
use Rector\Config\RectorConfig;
use Rector\Rector\AbstractRector;

final class FooRector extends AbstractRector
{
    private RectorConfig $rectorConfig;

    public function __construct(RectorConfig $rectorConfig)
    {
        // It is a new RectorConfig empty container instance.
        $this->rectorConfig = $rectorConfig;
    }

    public function getNodeTypes(): array
    {
        // ...
    }

    public function refactor(Node $node): ?Node
    {
        // ...
    }
}

- Ensure singleton instance of RectorConfig
- Make RectorConfig accessible during bootstrap
- Call setInstance and bind RectorConfig::class to same instance
- Avoid missing or duplicate config when resolving services
Copilot AI review requested due to automatic review settings February 11, 2026 08:42
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes an issue where custom Rector rules that inject RectorConfig via constructor were receiving an empty instance instead of the properly configured container. The fix ensures that the RectorConfig instance created in LazyContainerFactory::create() is registered both as a static singleton and as a container instance.

Changes:

  • Register RectorConfig as static singleton using setInstance() to enable global access via Container::getInstance()
  • Register RectorConfig in the container itself using instance() to enable dependency injection

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@samsonasik
Copy link
Member

Why you need it? RectorConfig should not be injected in rector rule, you can configure via implements ConfigurableRectorInterface in the rector rule itself

@guanguans
Copy link
Contributor Author

guanguans commented Feb 11, 2026

@samsonasik I want to get the container instance more flexible to handle something, unrelated to the ConfigurableRectorInterface, something like this code:

<?php

use PhpParser\Node;
use Rector\Config\RectorConfig;
use Rector\Rector\AbstractRector;

abstract class AbstractProxyRector extends AbstractRector
{
    protected AbstractRector $proxyRector;

    /**
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    public function __construct(RectorConfig $rectorConfig)
    {
        // RectorConfig::getInstance();
        $this->proxyRector = clone $rectorConfig->make($this->proxyRectorClass());
    }

    /**
     * {@inheritDoc}
     */
    public function refactor(Node $node)
    {
        // ...
    }

    /**
     * @return class-string<\Rector\Rector\AbstractRector>
     */
    abstract protected function proxyRectorClass(): string;
}

@TomasVotruba
Copy link
Member

TomasVotruba commented Feb 11, 2026

RectorConfig is exclusively internal. Injecting container to rule is a bad practice.
What exactly is your issue/goal?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants