Git Product home page Git Product logo

rector-symfony's People

Contributors

alexander-schranz avatar amtee avatar carlos-granados avatar gander avatar guillaumesmo avatar haehnchen avatar johjohan avatar julienfastre avatar keulinho avatar khartir avatar kick-the-bucket avatar lenny4 avatar malteschlueter avatar marmichalski avatar mikeamelung avatar mkrauser avatar mrardon avatar mttsch avatar mvhirsch avatar philippschreiber avatar romainjanvier avatar sabbelasichon avatar samsonasik avatar staabm avatar stefantalen avatar stephanvierkant avatar tiefschwarz avatar tomasvotruba avatar vincentlanglet avatar wkania avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rector-symfony's Issues

GetRequestRector blindly stubs any method called getRequest, even if it's not a controller class

In my home-brewed API client class, that is just a stand-alone class with no inheritance whatsoever, GetRequestRector decides to replace $this->getRequest() calls anyway, despite such a method not returning a Symfony Request object.

class MyClass {
-    public function createSandbox()
+    public function createSandbox(\Symfony\Component\HttpFoundation\Request $request)
     {
         $tempClientId = $this->clientId;

@@ @@

         $this->clientId = 'clients';

-        $request = $this->getRequest(
-            '/',
-            [
-            'ClientId' => 'foo',
-            'Name'     => 'bar',
-            'Email'    => 'baz',
-            ],
-            HttpRequestInterface::METHOD_POST,
-            false
-        );
+        $request = $request;
    }
}

It seems to me that, in order for such a substitution to be a valid candidate, the class must extend the Symfony base controller class to implement a version of $this->getRequest() that is compatible with this replacement, and Rector should be checking that.

Feature/Support: Migrate route configuration from yaml to annotation/attribute

Feature Request

I'm actually working on a legacy application with Symfony 3.4 and everything is structured in not necessary bundles. Actually the ~500 routes of the application are configured with YAML in the different bundles. My target is to migrate the route configuration to annotations or attributes. For the beginning I prefer annotations because there are already Rector rules which converts routes between annotations and attributes and legacy applications may not use PHP 8^^

I've already seen that somebody asked for this feature but no one has implemented it or not?

My first step was to get the resolved routes from Symfony because of the bundle structure a route configuration in YAML for a controller/action looks like FooBundle:Bar:baz and will be resolved by the router to \FooBar\FooBundle\Controller\Bar::bazAction which makes me easily to get the correct controller and especially the action because inside the Controller there are often more than one action implemented. For testing I implemented a Symfony command which iterates through the existing routes from the Symfony router and every information of route like path, name, default, ... are available. Very easy to get the important information.

Now the PHP files must be edited which will be easy with Rector but I don't know if it possible to iterate over the configured routes instead of iterating over directories/files?

If it's not possible maybe it's possible to extend the Symfony command which I used for testing that it can use Rector to edit the PHP files but the isn't my prefered solution because it wouldn't be a contribution to the Rector project but I publish it on GitHub.

WDYT?
I'm very open for any input :)

Diff

-foo_baz:
-    path: /foo/{baz}
-    defaults: { _controller: FooBundle:Bar:baz, _format: json }
-    methods: [ GET, POST ]

+/**
+ * @Route(name="foo_baz", path="/foo/{baz}", methods={"GET","POST"}, defaults={_format="json"})
+ */
public function bazAction(string $baz)

Question about using rector on a bundle

Hi there,

that might be a dumb question, but I'm still on a learning curve from being an engineer only to also developer, but here is the situation.
We've written a bundle with some clients, services and so on, which we are using on almost all projects internally.

I've already noticed, that the code quality could be a lot better, but I would like to check it via rector check as well, but obviously, there is no container loaded, so there isn't any container XML available.

I've already tried to include the bundle specifically in one of the projects by adding it to the $rectorConfig->paths, but it seems to ignore that directory (analyzed file count doesn't change).

Any hint would be appreciated.

Thanks !

Regards
Oliver

[Symfony 6.0] Extend set with known BC breaks

Is there a Rector for Symfony service name migrations?

It's nice that that's lots of little Rectors for doing simple things, but it seems to me the most laborious and complex task of upgrading an old Symfony project is upgrading to the new Symfony 3.3 configuration. Specifically, this means replacing service "machine names" (e.g. my.foo) with FQCN names (e.g. My\Foo::class).

Without this, SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION cannot do its job and isn't very helpful, because it only promotes services called via get() that specify FQCN class names already. In older projects, this means little or no services are fixed because machine names for services were the norm back then. Nevertheless, it should be possible to read the service configuration and map those names back to the actual class names to both perform the constructor injection and rename the service. However, I cannot find any Rector to do this.

[ERROR] Class 'Rector\Arguments\Rector\ClassMethod\ArgumentDefaultValueReplacerRector' not found

It appears that the class ArgumentDefaultValueReplacerRector moved from Rector\Arguments\Rector\ClassMethod\ArgumentDefaultValueReplacerRector to Rector\Arguments\ArgumentDefaultValueReplacer. However, the old name is still referenced in 3 places in rector-symfony: symfony28, symfony31, and symfony42. It's also used in nette's 30 setlist.

It looks like the class ArgumentDefaultValueReplacer also moved, and it's used in symfony28, so there are probably others that have moved, as well. But I can't see those errors until the first one is fixed.

Here's a demo showing the problem:

https://getrector.org/demo/b24fa402-ce3b-4f46-a9f6-3ed93e75d9c8

I am using rector/rector 0.11.20.

Allowing some rules to be apply on AbstractController, not only on the old Controller

Rules concerned:

  • AddFlashRector
  • RedirectToRouteRector

These are not applied when we already have the new extends AbstractController because they are only applied if the file is a subclass of the old "Symfony\Bundle\FrameworkBundle\Controller\Controller"

If the issue is validated by the maintainers, I could make a PR about this one.

I was thinking to update in this way, but maybe you want another way:
OLD

if (!$classReflection->isSubclassOf('Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller')) {
            return null;
        }

NEW

if (!$classReflection->isSubclassOf('Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller')
|| !$classReflection->isSubclassOf('Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController')) {
            return null;
        }

Inheritance issue with MakeCommandLazyRector rule

Hi,
I am using the tool in one Symfony project I have and I having this issue:
I have an abstract class which is extending the Command class (Symfony\Component\Console\Command\Command). It is like this:

abstract class AbstractExampleCommand extends Command
{
    public function __construct(private string $foo)
    {
        parent::__construct();
    }
}

Then I have my command class, which is extending the one explained before. It is like this:

class MyCommand extends AbstractCommand
{
    protected static $defaultName = 'app:command';
    
    public function __construct(string $foo)
    {
        parent::__construct($foo);
    }
}

And the Rector tool is suggesting me the following fix:

    ---------- begin diff ----------
@@ @@

 class MyCommand extends AbstractCommand
 {
+    protected static $defaultName = $foo;
     protected static $defaultName = 'app:command';

     public function __construct(
@@ @@
         string $foo
     ) {
-        parent::__construct($foo);
+        parent::__construct();
     }

     protected function execute(InputInterface $input, OutputInterface $output): int
    ----------- end diff -----------

Applied rules:
 * MakeCommandLazyRector

I think it is checking the constructor from the Symfony command class in some way and this is a wrong behavior.
I hope this helps.

`CountOnNullRector` doesn't resolve return type of doctrine repository method

Wasn't sure if this should go here or https://github.com/rectorphp/rector-doctrine, but I was unable to reproduce with only doctrine, so opted for this repo.

Reproducible code is a bit much for this, but some example code would be like:

<?php

declare(strict_types=1);

namespace App\Service;

use App\Entity\Card;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'test')]
class TestCommand extends Command
{
    public function __construct(
        private readonly EntityManagerInterface $em,
    ) {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        count($this
            ->em
            ->getRepository(Card::class)
            ->getFooCards()
        );

        return 0;
    }
}

where the CardRepository is like:

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\EntityRepository;

class CardRepository extends EntityRepository
{
    public function getFooCards(): array
    {
        return $this
            ->findBy([
                'rarity' => 'foo'
            ]);
    }
}

From here, assuming you setup a symfony project, some database that has a rarity column, and set your PHP/XML container files, running rector updates the command to be like:

is_countable($this
    ->em
    ->getRepository(Card::class)
    ->getFooCards()) ? count($this
    ->em
    ->getRepository(Card::class)
    ->getFooCards()
) : 0;

Given the container is provided, I would have expected it to be able to resolve the return type of the proper repository method.

It does work correctly if you manually assign the repo to a var and type it accordingly. E.g.

/** @var CardRepository $repo */
$repo = $this->em->getRepository(Card::class);

count($repo->getFooCards());

[Question] Symfony 4.4 to 5.4 with a lot of vendors

Hi,

I have to update a project running on Symfony 4.4 to version 5.4. This project has a lot of libraries and bundles and I'm having trouble synchronizing the vendors for each step.

Is it possible to perform all steps from version 4.4 to version 5.4 without updating vendors and then update vendors when my project is in version 5.4?

Thanks in advance for the help

Less dependencies

Hello,
Congratulations on your work on Rector.
Is it possible for rector-symfony to have less dependencies (or even 0 dependencies) like Rector?
Thanks

AssertLength convert bug?

converts

     * @Assert\Length(
     *     max="255",
     *     maxMessage="some Message"
     * )

to

#[Assert\Length(max: '255', maxMessage: 'some Message')]

but correct is

#[Assert\Length(max: 255, maxMessage: 'some Message')]

thrown error

TypeError : Symfony\Component\Validator\Constraints\Length::__construct(): Argument #3 ($max) must be of type ?int, string given

Ruleset
$containerConfigurator->import(SymfonySetList::SYMFONY_54);

Used Versions
SF 5.4
PHP 8.0
rector/rector: 0.12.5

SYMFONY_CONSTRUCTOR_INJECTION blind spot

SYMFONY_CONSTRUCTOR_INJECTION does not replace occurrences of $this->container->get('my.service');.

Notes

  • It does work for $this->get('my.service') and even $this->getContainer()->get('my.service').
  • $container is provided by ContainerAwareTrait.

Set symfony30. PropertyAccess is not a valid method name

Rector version 0.13.9

 vendor/bin/rector process  (--dry-run)
[ERROR] "Symfony\Component\PropertyAccess\PropertyAccess" is not a valid method name in
         /XXX/vendor/rector/rector/vendor/rector/rector-symfony/src/Set/../../config/sets/symfony/symfony30.php (which is being imported from "/XXX/vendor/rector/rector/vendor/rector/rector-symfony/src/Set/../../config/sets/symfony/level/up-to-symfony-30.php").

ControllerMethodAnalyzer::isAction may return true for private/protected functions

the issue is located here

Even if the name of the containing class ends with "Controller", imho a private or protected method cannot be action. Or am I missing something here?

Also, the Action-Suffix is not enough evidence either. It's use is discouraged. So the only thing we are left with, is to check if the method is inside a controller and see if it is public and not static.

Checking for an existing route to that controller is not an option, because there may be actions without a route. This is often used for internal sub-requests.

I'll submit a PR.

Thank you!

Cannot autowire service since version 0.11.0/0.11.1

If I missed something, please accept my apologies. I've just upgraded rector and installed rector-symfony and it failed, so I created a simple composer project to test that; below are my findings.

For each version of composer.json below, I'm simply running the command vendor/bin/rector

This composer.json works properly:

{
    "require-dev": {
        "rector/rector": "0.10.20",
        "rector/rector-symfony": "0.10.6"
    },
    "require": {}
}


This one:

{
    "require-dev": {
        "rector/rector": "0.11.0",
        "rector/rector-symfony": "0.11.0"
    },
    "require": {}
}

throws this error:

PHP Warning: include(/.../test/vendor/rector/rector/vendor/composer/../nette/utils/src/Utils/Strings.php): Failed to open stream: No such file or directory in /.../test/vendor/rector/rector/vendor/composer/ClassLoader.php on line 478
Warning: include(/.../test/vendor/rector/rector/vendor/composer/../nette/utils/src/Utils/Strings.php): Failed to open stream: No such file or directory in /.../test/vendor/rector/rector/vendor/composer/ClassLoader.php on line 478
PHP Warning: include(): Failed opening '/.../test/vendor/rector/rector/vendor/composer/../nette/utils/src/Utils/Strings.php' for inclusion (include_path='.:') in /.../test/vendor/rector/rector/vendor/composer/ClassLoader.php on line 478
Warning: include(): Failed opening '/.../test/vendor/rector/rector/vendor/composer/../nette/utils/src/Utils/Strings.php' for inclusion (include_path='.:') in /.../test/vendor/rector/rector/vendor/composer/ClassLoader.php on line 478

[ERROR] Class "RectorPrefix20210513\Nette\Utils\Strings" not found


And this one (including all later versions if I remember correctly):

{
    "require-dev": {
        "rector/rector": "0.11.1",
        "rector/rector-symfony": "0.11.1"
    },
    "require": {}
}

throws this:

[ERROR] Cannot autowire service "Rector\Symfony\Composer\ComposerNamespaceMatcher": argument "$smartFileSystem" of method "__construct()" has type "Symplify\SmartFileSystem\SmartFileSystem" but this class was not found.

Similar issue may be affecting Doctrine and PHPUnit subrepos.

SymfonySetList::SYMFONY_43 causes: Analyze error: "Class PHPUnit\Framework\TestCase not found."

Even on the older Rector v0.11.60, SymfonySetList::SYMFONY_43 causes almost every file to emit the following error once analysis completes (src/Kernel.php varies to all the other project file names between each error message emitted):

[ERROR] Could not process "src/Kernel.php" file, due to:
"Analyze error: "Class PHPUnit\Framework\TestCase not found.". Include your files in
"$parameters->set(Option::AUTOLOAD_PATHS, [...]);" in "rector.php" config.
See https://github.com/rectorphp/rector#configuration".

I've tried setting Option::AUTOLOAD_PATHS, although I don't know what I should set it to. I've tried setting --autoload-file on the command line, since I'm running inside Docker so perhaps rectorphp/rector#5104 might apply, but none of these changes fixes the issue. No prior Symfony set list needs this additional configuration, nor does the one after (SYMFONY_44).

The error is particularly strange since I am only running Rector on the src dir and there should be no references to any test classes in there.

Note: this may be a duplicate of #43, where the reporter managed to narrow it down to this specific Rector: SimplifyWebTestCaseAssertionsRector, which I can now confirm is the source of the problem in this set.

Sets don't include implied sets from prior versions

Why doesn't SYMFONY_44 preset imply Symfony 4.3, 4.2, 4.1, 4.0, 3.4, etc.? It's not as if you can run Symfony 4.4 without the changes introduced by the versions before it. Including the Symfony 4.4 preset literally just adds ConsoleExecuteReturnIntRector and nothing else. Are you expected to manually list every single Symfony version below 4.4? If so, what's even the point of "sets"?

`CountOnNullRector` doesn't resolve console command array input arguments/options

Related to #175 but specific to array based input /arguments/options for console commands.

For example given:

<?php

declare(strict_types=1);

namespace App\Service;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function dump;

#[AsCommand(name: 'test')]
class TestCommand extends Command
{
    public function configure()
    {
        $this
            ->addArgument('vals', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'the values to sum');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        dump(count($input->getArgument('vals')));

        return 0;
    }
}

Running this without any arguments prints 0. But after running rector, it gets re-written to: dump(is_countable($input->getArgument('vals')) ? count($input->getArgument('vals')) : 0);.

I would expect it to be able to resolve that it's an array argument and know its value is always an array. It does work if you manually assign it to a variable and type it as an array:

/** @var array $vals */
$vals = $input->getArgument('vals');

dump(count($vals));

What is the proper way of using Symfony rulesets?

We have large application based on custom framework, but many of Symfony components are used. Unfortunately those packages are in different versions (from 3.4 to 5.3). I thought that when I add SymfonySetList::SYMFONY_44 ruleset all rulesets for previous versions are loaded too, but I took a look at those rulesets and I don't see any connection between them. So I've used -vvv and compared applied rules with single ruleset added against configuration with multiple SymfonySetList::SYMFONY_* rulesets and it looks like more rules were applied.

What is the recommended flow for such scenario? Because this package's documentation states:

To add a set to your config, use Rector\Symfony\Set\SymfonySetList class and pick one of constants

Thanks in advance 🙂

Issue with RedirectToRouteRector rule

namespace App\Controller\Admin;

use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Symfony\Component\Routing\Annotation\Route;

class DashboardController extends AbstractDashboardController
{
    private AdminUrlGenerator $adminUrlGenerator;

    public function __construct(AdminUrlGenerator $adminUrlGenerator)
    {
        $this->adminUrlGenerator = $adminUrlGenerator;
    }
    
    /**
     * @Route("/admin")
     */
    public function index(): Response
    {
        return $this->redirect($this->adminUrlGenerator->setController(UserCrudController::class)->generateUrl());
    }
}
use Rector\Symfony\Set\SymfonyLevelSetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $containerConfigurator->import(SymfonyLevelSetList::UP_TO_SYMFONY_54);
};

Results in:

    ---------- begin diff ----------
@@ @@

 class DashboardController extends AbstractDashboardController
 {
-    private AdminUrlGenerator $adminUrlGenerator;
-
-    public function __construct(AdminUrlGenerator $adminUrlGenerator)
-    {
-        $this->adminUrlGenerator = $adminUrlGenerator;
-    }
-
     /**
      * @Route("/admin")
      */
     public function index(): Response
     {
-        return $this->redirect($this->adminUrlGenerator->setController(UserCrudController::class)->generateUrl());
+        return $this->redirectToRoute(null);
     }
 }
    ----------- end diff -----------

With error:

[ERROR] Could not process "/path/vendor/rector/rector/vendor/rector/rector-symfony/src/Rector/MethodCal/RedirectToRouteRector.php" file, due to:  Undefined offset: 0". On line: 80

ContainerGetToConstructorInjectionRector should ignore PHPUnit or KernelTestCase classes

When having ContainerGetToConstructorInjectionRector activated it tries to refractor the PHPUnit KernelTestCase classes to constructor. But as this are not service this should be avoided.

I tried to contribute it but I found not yet a way how I can check in


if the $node is inside a PHPUnit TestCase class / KernelTestCase class.

Rector SetList::NAMING with Symfony Autowiring by type and name

Ref https://symfony.com/blog/new-in-symfony-4-2-autowiring-by-type-and-name


Issue

I do have this config on my Symfony config file:

# config/services.yaml

services:
    _defaults:
        autowire: true
        autoconfigure: true
        bind:
            string $env: '%kernel.debug%'
            $stateMachinePurchaseOrder: '@state_machine.purchase_order'

In a php class as service constructor:

    public function __construct(private readonly StateMachine $stateMachinePurchaseOrder, ...) {...}

With rector SetList::NAMING:

- private readonly StateMachine $stateMachinePurchaseOrder
+ private readonly StateMachine $stateMachine

and thus it breaks the autowiring of Symfony services binded via name


Question

Is it possible in some way to configure/exclude/other this to not be "fixed"?

Thank you

Service machine names to class names Rector

In Symfony 2, service names were usually hand-crafted and later dubbed "machine names" in the upgrade guide. These days, service names are expected to match class names, except in the case where multiple service definitions exist for the same class. That is, generally we wish to automate this transformation:

-<service id="foo.bar" class="Foo\Bar">
+<service id="Foo\Bar">
     <argument>foo</argument>
 </service>

To just do that change as a search & replace is easy, but to do it for thousands of services needs to be automated because we don't know the machine names for every class without looking up each one individually.

[Symfony 4.4][Security] AuthorizationChecker::isGranted() and ListenerInterface not detected

Running Rector with SF 4.4 as target, it doesn't look like it is detecting the deprecation for this change

Deprecated passing more than one attribute to AccessDecisionManager::decide() and AuthorizationChecker::isGranted() (and indirectly the is_granted() Twig and ExpressionLanguage function)

declare(strict_types=1);

use Rector\Core\Configuration\Option;
use Rector\Symfony\Set\SymfonyLevelSetList;
use Rector\Core\ValueObject\PhpVersion;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    // get parameters
    $parameters = $containerConfigurator->parameters();
    $parameters->set(Option::BOOTSTRAP_FILES, [
        __DIR__ . '/vendor/autoload.php',
        __DIR__ . '/bin/.phpunit/phpunit-6.5/vendor/autoload.php',
    ]);
    $parameters->set(
        Option::PHP_VERSION_FEATURES,
        PhpVersion::PHP_74
    );
    $parameters->set(
        Option::SYMFONY_CONTAINER_XML_PATH_PARAMETER,
        __DIR__ . '/var/cache/dev/App_KernelDevDebugContainer.xml'
    );

    $containerConfigurator->import(SymfonyLevelSetList::UP_TO_SYMFONY_44);
};

File analyzed with vendor/bin/rector process src/App/Service/FooService --dry-run

namespace App\Service;
  
use Symfony\Component\Security\Guard\AuthenticatorInterface;
use Symfony\Component\Security\Http\Firewall\ListenerInterface;
  
class FooService
{

    
    /** @var AuthorizationCheckerInterface */
    private $auth;
    /** @var ListenerInterface */
    private $listener;

    public function __construct(
        AuthorizationCheckerInterface $auth,
        ListenerInterface $listener
    ) {
        $this->auth= $auth;
        $this->listener= $listener;
    }
    
    public function foo() {
        if ($this->auth->isGranted(['ROLE_USER', 'ROLE_ADMIN'])) {
            die();
        }
   }
}

The Rule set for Symfony 4.4 seems to only include elements concerning the console and nothing else

I suspect I might have missed something of misused/misconfigured the script but wanted to open an Issue to be sure.

Symfony 51 rector rule incorrectly rewrites Responses

Hi Tomas,

I'm working on upgrading Symfony 4.4 application to 5.3 and I'm using your amazing tool to help me with that process. However, I encountered an incorrect change of code for the static Response::create() method to new Response() in one of the rules.

Here is original code:

class TestController extends AbstractController
{
	public function someAction(): JsonResponse
	{
		return JsonResponse::create(['data' => '...'], Response::HTTP_OK);
	}
}

Rector configuration (using version ^0.12.5):

return static function (ContainerConfigurator $containerConfigurator): void {
	// get parameters
	$parameters = $containerConfigurator->parameters();
	$parameters->set(Option::PATHS, [
		__DIR__ . '/src',
	]);

	$parameters->set(Option::BOOTSTRAP_FILES, [
		__DIR__ . '/vendor/autoload.php'
	]);

	$containerConfigurator->import(SymfonyLevelSetList::UP_TO_SYMFONY_51);
};

Here is the result after running rector:

1) src/Controller/TestController.php:10

    ---------- begin diff ----------
@@ @@

        public function someAction(): JsonResponse
        {
-               return JsonResponse::create(['data' => '...'], Response::HTTP_OK);
+               return new \Symfony\Component\HttpFoundation\JsonResponse();
        }
 }
    ----------- end diff -----------

Applied rules:
 * StaticCallToNewRector (https://github.com/symfony/symfony/pull/35308)

I think that the rule should preserve the arguments of the create() method when refactoring to the new form to avoid breaking app logic.

A minimum working repository is here: https://github.com/fvozar/rector-symfony-response-rector-bug

SymfonyLevelSetList::UP_TO_SYMFONY_42 BrowserKit crawler method update parsing throws exception

When bumping the SymfonyLevelSetList of a legacy application to UP_TO_SYMFONY_42, parsing the code resulted in the following exception:

[ERROR] Could not process "tests/Controller/Test.php" file, due to:                                  
         "System error: "Invalid identifier name "[]""

I've chased that down to the following minimal code that will trigger the failure above:

/** @test */
public function formTest(): void
{
    $client = static::createClient();

    $crawler = $client->request('GET', '/api/path/here');

    $form = $crawler->selectButton('Button Text Here')->form();

    $client->submit($form);

}

I've traced that code triggering the behavior as far as https://github.com/rectorphp/rector-symfony/blob/main/config/sets/symfony/symfony42.php#L66

With that knowledge, I modified the code above to the following:

/** @test */
public function formTest(): void
{
    $client = static::createClient();

    $crawler = $client->request('GET', '/api/path/here');

    $form = $crawler->selectButton('Button Text Here')->form();

    $client->submit($form, []);
}

Doing so resolves the exception and allows rector to complete analysis of all code; however, it proposes a change incompatible with the function:

-        $client->submit($form, []);
+        $client->submit($form, [], []);

With symfony/browser-kit 4.4.37 vendored, the submit function has the following signature:

public function submit(Form $form, array $values = [])

Given the above, I can work around this for the time being, but wanted to document this issue I encountered.

Rector failed on default Symfony config run if PHPUnit is not installed.

See "Class PHPUnit\Framework\TestCase not found." error in the output:

$ ./vendor/bin/rector process src/


 [WARNING] Your project requires min PHP version "7.4".

           1 Rector rules defined in your configuration require higher PHP version and will not run,
           to avoid breaking your codebase, use -vvv for detailed info.


 ! [NOTE] Do you want to run them? Make "require" > "php" in `composer.json` higher,
 !        or add "Option::PHP_VERSION_FEATURES" parameter to your `rector.php`.


In RuntimeReflectionProvider.php line 185:

  Class PHPUnit\Framework\TestCase not found.


process [-n|--dry-run] [-a|--autoload-file AUTOLOAD-FILE] [--no-progress-bar] [--no-diffs] [--output-format OUTPUT-FORMAT] [--memory-limit MEMORY-LIMIT] [--clear-cache] [--port PORT] [--identifier IDENTIFIER] [--] [<source>...]

Just for the reference, my rector.php config is:

return static function (ContainerConfigurator $containerConfigurator): void {
    // region Symfony Container
    $parameters = $containerConfigurator->parameters();
    $parameters->set(
        Option::SYMFONY_CONTAINER_XML_PATH_PARAMETER,
        __DIR__ . '/var/cache/dev/App_KernelDevDebugContainer.xml'
    );
    // endregion

    $containerConfigurator->import(SymfonyLevelSetList::UP_TO_SYMFONY_54);
    $containerConfigurator->import(SymfonySetList::SYMFONY_CODE_QUALITY);
    $containerConfigurator->import(SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION);
};

Installing PHPUnit is a workaround for this.

`StringToArrayArgumentProcessRector` doesn't handle `sprintf` command string

Bug Report

Subject Details
Rector version last dev-main
Installed as composer dependency

Minimal PHP Code Causing Issue

See https://getrector.org/demo/a1df00ad-a417-4342-8040-3d2e0562e70a

<?php

use Symfony\Component\Process\Process;

$command = sprintf("FOO=%s", 10);

$process = new Process($command);

Responsible rules

  • StringToArrayArgumentProcessRector

Expected Behavior

Probably would be easiest to skip it, as migrating the sprintf call could lead to wrong results and be quite tricky, if not impossible.

Upgrading to 0.12.3 gives "Method getExtendedTypes() was not found in reflection of class Symfony\Component\Form\AbstractTypeExtension"

It seems that, after Rector finishes its first run after upgrading from 0.11 -> 0.12, almost every file in my project is attributed to an error similar to the following:

[ERROR] Could not process "src/Kernel.php" file, due to:
"Method getExtendedTypes() was not found in reflection of class Symfony\Component\Form\AbstractTypeExtension.".
On line: 328

Of course, the source file (Kernel.php) is different in each case, but otherwise the error is the same for every single file. Many of these files do not even appear to be tangentially related to the Form component in any way, so I have no idea what is going on.

This occurs on Symfony 4.4.33.

The getContainer method on the Kernel should not be refractored to DependencyInjection

In most cases it make sense that rector is refractoring getContainer calls to dependency injection.

But if the class which is refractored is from class Symfony\Component\HttpKernel\Kernel it should be kept that way. I think the there is already an exception for this rule added for KernelTestCase. The Kernel class should also be added as exception for this.

Example: https://github.com/sulu/sulu/blob/e9c3de51ecaca82fb728535c12ec822840922e02/src/Sulu/Bundle/AudienceTargetingBundle/Tests/Application/Kernel.php#L35

Bildschirmfoto 2022-04-26 um 15 42 54

My used rector.php:

<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Core\Configuration\Option;
use Rector\Symfony\Set\SymfonyLevelSetList;

return static function (RectorConfig $rectorConfig): void {
    $parameters = $rectorConfig->parameters();

    $rectorConfig->paths([
        __DIR__ . '/src',
        __DIR__ . '/tests',
    ]);

    $rectorConfig->importNames();
    $parameters->set(Option::IMPORT_SHORT_CLASSES, false);

    $rectorConfig->sets([
        SymfonyLevelSetList::UP_TO_SYMFONY_54,
    ]);

    $parameters->set(
        Option::SYMFONY_CONTAINER_XML_PATH_PARAMETER,
        __DIR__ . '/var/cache/admin/dev/App_KernelDevDebugContainer.xml',
    );
};

I also found other classes which requires to still have the container:

Symfony Userinterface::getUsername => getUserIdentifier only for Symfony >= 6.0

Symfony changes the name getUsername in the UserInterface to getUserIdentifier with Symfony 6.0.

Using the new name works starting at Symfony 5.3, but since the UserInterface is not changed yet, renaming the method in Symfony 5.3 and 5.4 will break the code, since the User-Class implementing the Interface is missing getUsername()

This Rule should be moved to the Symfony 6.0 set.

see
https://github.com/symfony/symfony/blob/5.3/src/Symfony/Component/Security/Core/User/UserInterface.php

Feature idea: Add the Symfony\Component\Console\Attribute\AsCommand attribute

As of Symfony 6.1, I've got this notification in my logs:

Since symfony/console 6.1: Relying on the static property "$defaultDescription" for setting a command description is deprecated. Add the "Symfony\Component\Console\Attribute\AsCommand" attribute to the "App\Command\NotificationCommand" class instead.

I'd the great if Rector can refactor commands with static $defaultName and static $defaultDescription.

Merge SymfonySetList and SymfonyLevelSetList

I personally struggle all the time getting the correct import for the UP_TO_SYMFONY_61 rule sets.
Would find it better if the SetList and LevelSetList are merged into a single imported file so I find them at the same place. As sometimes I switching from UP_TO_* to single version and vise-versa when doing step by step updates, but have then always import the one or the other file make it a better developer experience from my point of view.

False positive error when used in projects which don't have PHPUnit installed

SimplifyWebTestCaseAssertionsRector throws a false positive while doing the $classReflection->isSubclassOf('Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase') check if PHPUnit isn't available in the class loader.

A similar issue also occurs in mglaman/phpstan-drupal#215 for reference purposes.

The output from running rector is something along the lines of:

 [ERROR] Could not process
         "web/modules/custom/custom_module/src/EventSubscriber/CustomSubscriber.php" file,
         due to:
         "Analyze error: "Class PHPUnit\Framework\TestCase not found.". Include your files in
         "$parameters->set(Option::AUTOLOAD_PATHS, [...]);" in "rector.php" config.
         See https://github.com/rectorphp/rector#configuration".

Error on DependencyInjectionMethodCallAnalyzer fails on Trait

Rectors fails with:

1580/4763 [▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░]  33%
In DependencyInjectionMethodCallAnalyzer.php line 49:

  Look at "Rector\Symfony\NodeAnalyzer\DependencyInjectionMethodCallAnalyzer::replaceMethodCallWithPropertyFetchAndDependency()" on line 49
Stack Trace
[refactoring] src/Sulu/Bundle/TestBundle/Testing/PhpCrInitTrait.php
    [applying] Rector\Symfony\Rector\ClassMethod\ConsoleExecuteReturnIntRector
    [applying] Rector\Symfony\Rector\BinaryOp\ResponseStatusCodeRector
    [applying] Rector\Symfony\Rector\MethodCall\ContainerGetToConstructorInjectionRector
PHP Fatal error:  Uncaught Rector\Core\Exception\ShouldNotHappenException: Look at "Rector\Symfony\NodeAnalyzer\DependencyInjectionMethodCallAnalyzer::replaceMethodCallWithPropertyFetchAndDependency()" on line 49 in /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/rector/rector-symfony/src/NodeAnalyzer/DependencyInjectionMethodCallAnalyzer.php:49
Stack trace:
#0 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/rector/rector-symfony/src/Rector/MethodCall/ContainerGetToConstructorInjectionRector.php(95): Rector\Symfony\NodeAnalyzer\DependencyInjectionMethodCallAnalyzer->replaceMethodCallWithPropertyFetchAndDependency(Object(PhpParser\Node\Expr\MethodCall))
#1 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Rector/AbstractRector.php(249): Rector\Symfony\Rector\MethodCall\ContainerGetToConstructorInjectionRector->refactor(Object(PhpParser\Node\Expr\MethodCall))
#2 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(113): Rector\Core\Rector\AbstractRector->enterNode(Object(PhpParser\Node\Expr\MethodCall))
#3 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Return_))
#4 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105): PhpParser\NodeTraverser->traverseArray(Array)
#5 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\ClassMethod))
#6 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105): PhpParser\NodeTraverser->traverseArray(Array)
#7 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Trait_))
#8 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105): PhpParser\NodeTraverser->traverseArray(Array)
#9 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Namespace_))
#10 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(85): PhpParser\NodeTraverser->traverseArray(Array)
#11 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(52): PhpParser\NodeTraverser->traverse(Array)
#12 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor.php(54): Rector\Core\PhpParser\NodeTraverser\RectorNodeTraverser->traverse(Array)
#13 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(132): Rector\Core\Application\FileProcessor->refactor(Object(Rector\Core\ValueObject\Application\File))
#14 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(144): Rector\Core\Application\FileProcessor\PhpFileProcessor->Rector\Core\Application\FileProcessor\{closure}(Object(Rector\Core\ValueObject\Application\File))
#15 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(133): Rector\Core\Application\FileProcessor\PhpFileProcessor->tryCatchWrapper(Object(Rector\Core\ValueObject\Application\File), Object(Closure), Object(Rector\Core\Enum\ApplicationPhase))
#16 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(91): Rector\Core\Application\FileProcessor\PhpFileProcessor->refactorNodesWithRectors(Object(Rector\Core\ValueObject\Application\File))
#17 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/ApplicationFileProcessor.php(76): Rector\Core\Application\FileProcessor\PhpFileProcessor->process(Object(Rector\Core\ValueObject\Application\File), Object(Rector\Core\ValueObject\Configuration))
#18 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/ApplicationFileProcessor.php(57): Rector\Core\Application\ApplicationFileProcessor->processFiles(Array, Object(Rector\Core\ValueObject\Configuration))
#19 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Console/Command/ProcessCommand.php(152): Rector\Core\Application\ApplicationFileProcessor->run(Array, Object(Rector\Core\ValueObject\Configuration))
#20 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/symfony/console/Command/Command.php(274): Rector\Core\Console\Command\ProcessCommand->execute(Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#21 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/symfony/console/Application.php(870): RectorPrefix20211020\Symfony\Component\Console\Command\Command->run(Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#22 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/symfony/console/Application.php(266): RectorPrefix20211020\Symfony\Component\Console\Application->doRunCommand(Object(Rector\Core\Console\Command\ProcessCommand), Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#23 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Console/ConsoleApplication.php(71): RectorPrefix20211020\Symfony\Component\Console\Application->doRun(Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#24 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/symfony/console/Application.php(162): Rector\Core\Console\ConsoleApplication->doRun(Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#25 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/bin/rector.php(63): RectorPrefix20211020\Symfony\Component\Console\Application->run()
#26 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/bin/rector(5): require_once('/Users/alexande...')
#27 {main}
  thrown in /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/rector/rector-symfony/src/NodeAnalyzer/DependencyInjectionMethodCallAnalyzer.php on line 49
Fatal error: Uncaught Rector\Core\Exception\ShouldNotHappenException: Look at "Rector\Symfony\NodeAnalyzer\DependencyInjectionMethodCallAnalyzer::replaceMethodCallWithPropertyFetchAndDependency()" on line 49 in /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/rector/rector-symfony/src/NodeAnalyzer/DependencyInjectionMethodCallAnalyzer.php:49
Stack trace:
#0 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/rector/rector-symfony/src/Rector/MethodCall/ContainerGetToConstructorInjectionRector.php(95): Rector\Symfony\NodeAnalyzer\DependencyInjectionMethodCallAnalyzer->replaceMethodCallWithPropertyFetchAndDependency(Object(PhpParser\Node\Expr\MethodCall))
#1 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Rector/AbstractRector.php(249): Rector\Symfony\Rector\MethodCall\ContainerGetToConstructorInjectionRector->refactor(Object(PhpParser\Node\Expr\MethodCall))
#2 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(113): Rector\Core\Rector\AbstractRector->enterNode(Object(PhpParser\Node\Expr\MethodCall))
#3 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Return_))
#4 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105): PhpParser\NodeTraverser->traverseArray(Array)
#5 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\ClassMethod))
#6 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105): PhpParser\NodeTraverser->traverseArray(Array)
#7 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Trait_))
#8 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(105): PhpParser\NodeTraverser->traverseArray(Array)
#9 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(196): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Namespace_))
#10 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(85): PhpParser\NodeTraverser->traverseArray(Array)
#11 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(52): PhpParser\NodeTraverser->traverse(Array)
#12 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor.php(54): Rector\Core\PhpParser\NodeTraverser\RectorNodeTraverser->traverse(Array)
#13 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(132): Rector\Core\Application\FileProcessor->refactor(Object(Rector\Core\ValueObject\Application\File))
#14 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(144): Rector\Core\Application\FileProcessor\PhpFileProcessor->Rector\Core\Application\FileProcessor\{closure}(Object(Rector\Core\ValueObject\Application\File))
#15 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(133): Rector\Core\Application\FileProcessor\PhpFileProcessor->tryCatchWrapper(Object(Rector\Core\ValueObject\Application\File), Object(Closure), Object(Rector\Core\Enum\ApplicationPhase))
#16 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/FileProcessor/PhpFileProcessor.php(91): Rector\Core\Application\FileProcessor\PhpFileProcessor->refactorNodesWithRectors(Object(Rector\Core\ValueObject\Application\File))
#17 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/ApplicationFileProcessor.php(76): Rector\Core\Application\FileProcessor\PhpFileProcessor->process(Object(Rector\Core\ValueObject\Application\File), Object(Rector\Core\ValueObject\Configuration))
#18 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Application/ApplicationFileProcessor.php(57): Rector\Core\Application\ApplicationFileProcessor->processFiles(Array, Object(Rector\Core\ValueObject\Configuration))
#19 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Console/Command/ProcessCommand.php(152): Rector\Core\Application\ApplicationFileProcessor->run(Array, Object(Rector\Core\ValueObject\Configuration))
#20 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/symfony/console/Command/Command.php(274): Rector\Core\Console\Command\ProcessCommand->execute(Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#21 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/symfony/console/Application.php(870): RectorPrefix20211020\Symfony\Component\Console\Command\Command->run(Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#22 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/symfony/console/Application.php(266): RectorPrefix20211020\Symfony\Component\Console\Application->doRunCommand(Object(Rector\Core\Console\Command\ProcessCommand), Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#23 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/src/Console/ConsoleApplication.php(71): RectorPrefix20211020\Symfony\Component\Console\Application->doRun(Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#24 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/symfony/console/Application.php(162): Rector\Core\Console\ConsoleApplication->doRun(Object(RectorPrefix20211020\Symfony\Component\Console\Input\ArgvInput), Object(RectorPrefix20211020\Symfony\Component\Console\Output\ConsoleOutput))
#25 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/bin/rector.php(63): RectorPrefix20211020\Symfony\Component\Console\Application->run()
#26 /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/bin/rector(5): require_once('/Users/alexande...')
#27 {main}
  thrown in /Users/alexanderschranz/Documents/Sulu/sulu-develop.localhost/vendor/sulu/sulu/vendor/rector/rector/vendor/rector/rector-symfony/src/NodeAnalyzer/DependencyInjectionMethodCallAnalyzer.php on line 49

Trailt which fails: https://github.com/sulu/sulu/blob/2.3.6/src/Sulu/Bundle/TestBundle/Testing/PhpCrInitTrait.php

Expected behaviour:

For me there are 2 solutions.

A: Ignore traits instead of failing here.

And the other one is:

B: Show File which was erroring in exception so its easier to find out which one should be add to skiped files.

Rules from Symfony 3.2 applys to Symfony 5.4

This sets contains rules for adding priority as a second argument to addCompillerPass method

When apply rule $containerConfigurator->import(SymfonyLevelSetList::UP_TO_SYMFONY_54); this rules also applys but method signature since symfony 3 was changed to https://github.com/symfony/symfony/blob/5.4/src/Symfony/Component/DependencyInjection/ContainerBuilder.php#L464 and priority now is the third argument

Diiff

     protected function build(ContainerBuilder $container): void
     {
-        $container->addCompilerPass(new FooPass());
+        $container->addCompilerPass(new FooPass(), 0);
     }

DependencyInjectionMethodCallAnalyzer does not check for existing properties

The mentioned class is used by rector to replace container usage with autowiring. Now imagine a class like this:

<?php

namespace Test;

use Symfony\Component\DependencyInjection\ContainerInterface;
use App\Registry;

class Test
{
    private ContainerInterface $container;
    private Registry $registry;

    public function __construct(ContainerInterface $container, Registry $registry)
    {
        $this->container = $container;
        $this->registry = $registry;
    }
    
    public function getRegistry(): Registry {
        return $this->registry;
    }

    public function flush() {
        return $this->container->get('doctrine')->getManager()->flush();
    }
}

The doctrine-Service is an instance of Doctrine\Bundle\DoctrineBundle\Registry.
The DependencyInjectionMethodCallAnalyzer wants to replace this call $this->container->get('doctrine') with a autowired property, which is fine. But in this case, the name for the new property is derived from the class of the service, in this case that would be "registry".
Rector sees that there already is a property named registry (but it's a different class) and doe not add a new property. But the call is still replaced with:

$this->registry->getManager()->flush();

which of course is wrong.

Here's the line where the variable name is guessed:

$propertyName = $this->propertyNaming->fqnToVariableName($serviceType);

I see two solutions:

  1. Check, if there's already a property of that name. If so, use a longer name. PropertyNaming does provide a function for this.
  2. Skip replacing the Container-Call, if there's a property of that name with a different type.

Cannot use with rector prefixed

It's not possible to install rector everywhere because of dependencies conflicts.
Rector prefixed makes it possible, but rector-symfony only allows rector to be used.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.