rectorphp / rector-symfony Goto Github PK
View Code? Open in Web Editor NEWRector upgrade rules for Symfony
Home Page: http://getrector.com
License: MIT License
Rector upgrade rules for Symfony
Home Page: http://getrector.com
License: MIT License
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.
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 :)
-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)
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
Resources with upgrade informations:
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.
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.
Rules concerned:
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;
}
SYMFONY_52
set with attributable configuration to transfer themHi,
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.
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());
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
Hello,
Congratulations on your work on Rector.
Is it possible for rector-symfony to have less dependencies (or even 0 dependencies) like Rector?
Thanks
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
does not replace occurrences of $this->container->get('my.service');
.
$this->get('my.service')
and even $this->getContainer()->get('my.service')
.$container
is provided by ContainerAwareTrait
.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").
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!
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.
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.
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"?
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));
If we're injecting a service into a form type, rector is attempting to rewrite the parameter as an option.
This shouldn't happen because we need a service injected from the container. Is there a reason this is a default rule?
When GetResponseForExceptionEvent is renamed to ExceptionEvent, we also need to fix the getException method to getThrowable.
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 🙂
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
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
$node
is inside a PHPUnit TestCase class / KernelTestCase class.Ref https://symfony.com/blog/new-in-symfony-4-2-autowiring-by-type-and-name
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
Is it possible in some way to configure/exclude/other this to not be "fixed"?
Thank you
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.
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.
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
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.
Hi
According to https://github.com/symfony/symfony/blob/6.0/UPGRADE-6.0.md, getDoctrine()
is being deprecated
I have a lot of code $em = $this->getDoctrine()->getManager();
in my controllers, I would like to know if there is, or how to add, a rule to swap from this code to EntityManagerInterface $entityManager
constructor injection or controller action injection
thank you
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.
Subject | Details |
---|---|
Rector version | last dev-main |
Installed as | composer dependency |
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);
StringToArrayArgumentProcessRector
Probably would be easiest to skip it, as migrating the sprintf
call could lead to wrong results and be quite tricky, if not impossible.
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.
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.
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
:
It seems GetParameterToConstructorInjectionRector
is hard-coded to only deal with Controllers (of type Controller
or AbstractController
), but there once existed ContainerAwareCommand
also, for which parameter injections may also be needed, in older code bases.
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.
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
.
SYMFONY_CONSTRUCTOR_INJECTION
replaces occurrences of $this->get('router')
with ServiceSubscriberInterface
instead of RouterInterface
.
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.
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".
Rectors fails with:
1580/4763 [▓▓▓▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░] 33%
In DependencyInjectionMethodCallAnalyzer.php line 49:
Look at "Rector\Symfony\NodeAnalyzer\DependencyInjectionMethodCallAnalyzer::replaceMethodCallWithPropertyFetchAndDependency()" on line 49
[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.
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);
}
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:
I see two solutions:
Why does the readme state this? This isn't even remotely true. SymfonySetList
doesn't even exist "in the box".
I had to modify xml path option to get rector working on some rules. I'm quite surprised that it didn't complain about it.
Is it a wanted behaviour ?
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.
$formBuilder
->add('name', 'text', array('label' => '...'))
->add(...)
->add('friends', 'collection', array(
- 'type' => new FriendType(),
+ 'entry_type' => new FriendType(),
- 'options' => array(...)
+ 'entry_options' => array(...)
))
;
This rule might be added, but I could not find it here. So please verify if we have it first. If not, it's should a new rule 🙂
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.