-
-
Notifications
You must be signed in to change notification settings - Fork 704
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect behavior of DowngradeParameterTypeWideningRector #8031
Comments
Using https://getrector.com/demo/b54d7404-7089-481e-a0e0-461b9df7f72d |
I tested with |
I think this is already correct, if it is not final class, the parameter is removed, and when final, it is leave as is, see |
Even the trait method is used by final class and overridden, it seems still changed, so I think it actually fine as both method that have methods are changed, see https://getrector.com/demo/c5a38bf3-1b42-4177-89d0-b5e671636041 |
Hmmm I'm not sure this is right, why should Removing the type can actually be harmful to the application, so I think it should be done only when it has to be done. For instance, because the PHP version does not support typed parameters. But PHP, all the way down to 7.1 and even below, supports typed arguments, so there's no need to remove them. I'll explain why removing the type is bad in my particular case (I believe that this same case might apply to Rector too, as it's also being downgraded and uses dependency injection): I use
To avoid this problem, I would now need to not make my class Also, this creates confusion when a trait is used by both https://getrector.com/demo/cffaa566-f8cc-4197-b0dd-838acdbcccb5 Take into account that these could be in different projects. For instance, in my case, I have a WordPress plugin providing a GraphQL server, and independent developers can extend the GraphQL schema via their own plugins. If their classes use the trait that I defined in my plugin, So unless I'm missing something, I don't see why Thoughts? |
Could you create sample use case when it broke app on https://getrector.org/demo or https://3v4l.org ? |
Here: https://getrector.com/demo/9f4833fb-d588-438e-b508-2ed96152f9bf I'm using the The code in PHP 8.1 that I'm downgrading is this one (this bug report at the top is a shortened version of this): trait WithInstanceManagerServiceTrait
{
protected InstanceManagerInterface $instanceManager;
#[Required]
final public function setInstanceManager(InstanceManagerInterface $instanceManager): void
{
$this->instanceManager = $instanceManager;
}
final protected function getInstanceManager(): InstanceManagerInterface
{
return $this->instanceManager;
}
} That This trait When downgraded with trait WithInstanceManagerServiceTrait
{
/**
* @var \PoP\Root\Instances\InstanceManagerInterface
*/
protected $instanceManager;
/**
* @param \PoP\Root\Instances\InstanceManagerInterface $instanceManager
* @required
*/
public final function setInstanceManager($instanceManager) : void
{
$this->instanceManager = $instanceManager;
}
protected final function getInstanceManager() : InstanceManagerInterface
{
return $this->instanceManager;
}
} Notice that the type With trait WithInstanceManagerServiceTrait
{
/**
* @var \PoP\Root\Instances\InstanceManagerInterface
*/
protected $instanceManager;
/**
* @required
*/
public final function setInstanceManager(InstanceManagerInterface $instanceManager) : void
{
$this->instanceManager = $instanceManager;
}
protected final function getInstanceManager() : InstanceManagerInterface
{
return $this->instanceManager;
}
} Notice that the type |
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\DowngradeLevelSetList;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->sets([
DowngradeLevelSetList::DOWN_TO_PHP_71,
]);
$rectorConfig
->ruleWithConfiguration(\Rector\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector::class, [
WithInstanceManagerServiceTrait::class => ['getInstanceManager'],
]);
}; see https://getrector.com/demo/ac050d1f-fa18-40f8-9999-73ade354368c is that will work for you? |
I guess it should work. I'll check tomorrow or Monday (now I'm busy with something). The thing I need to check is how many such methods I need to add into the configuration. If it's only one ( Question: Souldn't the configuration work the opposite way? i.e.:
Then if you really want that behavior (that, in my opinion, is not the expected behavior from that PHP feature), only then you explicitly enable it. Also: Can it be enabled/disabled globally? (i.e. instead of having to define class by class and method by method, as in this example you provided) Thoughts? |
I just noticed that, in the example you sent, |
That probably different issue or caused by multiple rules apply, could you narrow to specific rule that cause it not apply |
@leoloso you're missing use statement: use Symfony\Contracts\Service\Attribute\Required; in the example code, the following convert to https://getrector.com/demo/8d49074d-319b-4a99-a6ef-a5a148cfecb7 |
@samsonasik I did the config change (GatoGraphQL/GatoGraphQL#2396), and that specific file was downgraded OK, but the application is exploding somewhere else:
You can see the issue happens on Symfony DependendyInjection and Symfony Config dependencies, so this code is out of my control. The error says that the same function from a class and its parent class was downgraded differently. Class use PrefixedByPoP\Symfony\Component\Config\Loader\FileLoader as BaseFileLoader;
abstract class FileLoader extends BaseFileLoader Then, this is how function In public function import($resource, string $type = null, $ignoreErrors = \false, string $sourceResource = null, $exclude = null) Notice that In public function import($resource, string $type = null, bool $ignoreErrors = \false, string $sourceResource = null, $exclude = null) Notice that Could it be that |
Here I recreated it: https://getrector.com/demo/63323a2d-5182-4469-8d5a-6fca29baba85 But it seems to be downgraded alright there? Btw, notice that the signature of |
Could it be that one class is implemented by some |
Here it goes, I reproduced the issue: https://getrector.com/demo/44f3d3df-8a0c-454b-8e5b-049fc00cb511 When adding this: $rectorConfig
->ruleWithConfiguration(\Rector\DowngradePhp72\Rector\ClassMethod\DowngradeParameterTypeWideningRector::class, [
WithInstanceManagerServiceTrait::class => ['getInstanceManager'],
]); ...the If not adding that config code, then both |
The issue probably on other rules, as when only apply the could you narrow to specific rules that cause it? |
It is https://getrector.com/demo/1cbb1dd6-8f37-4ac2-a284-5d22d8859a6e |
It's independent of having that config or not: https://getrector.com/demo/377c6d23-e96a-48df-b48a-9266b7429d55 |
Having both
https://getrector.com/demo/b517fe20-c542-4896-993c-f4f199416dff
https://getrector.com/demo/a7349da0-8687-4045-96d2-a375e14aed79 |
It seems due to the rule use Reflection that may be cached, could you try provide failing test case PR with configured rule provided and expected fixture output at https://github.com/rectorphp/rector-downgrade-php/tree/main/tests/Issues/IssueDowngradeArraySpread Thank you. |
@samsonasik Done, please check: rectorphp/rector-downgrade-php#140 |
Test recreated successfully, it's failing as it should: https://github.com/rectorphp/rector-downgrade-php/actions/runs/5461465950/jobs/9939590731?pr=140 /**
* @param string|mixed[] $exclude
*/
- public function import($ignoreErrors = false, string $sourceResource = null, $exclude = null)
+ public function import(bool $ignoreErrors = false, string $sourceResource = null, $exclude = null)
{
}
} |
@leoloso I think the solution is define both That will work on php 7.1. |
Hmmmm I find this solution unsatisfactory to be honest, because I don't know in advance what code will need to be downgraded, using what rule. The example itself involves 2 libraries from Symfony, which I don't know anything about. So with the proposal to add Also, the GitHub Action task running the downgrade takes around 10 minutes, and after that one I might discover that the downgraded code fails somewhere else, so I'd need to find the source of the problem, apply the config also there, test again, and so on. This is far from ideal. Instead of running Rector and having everything automatically work, it'll now become a process prone to failures that I need to manually fix, without ever knowing if that's conflicting with something else, or if there's another bug somewhere else that I haven't identified with my tests and will then explode in runtime. Back to my previous comment (#8031 (comment)):
Can this be done? In other words, invert the behavior: Have Rector by default work always in a fail-safe way, and only for people who know what they are doing, they can enable configuration to customize the behavior (eg: removing the type for I keep thinking that the type should not be removed for What do you think? |
Not downgrading final class seems will cause another bug if it has interface that downgraded, see https://3v4l.org/UmLn9#v7.1.33 which the final class's method param is not compatible with interface, and the child of interface can be final or not, so to be safe, just mark all of them non typed. The hardest part of it is keeping work with php 7.1 tbh |
I don't understand why |
That's will be a bug that happen if we are going to apply |
I may be confused, but why will only the interface be downgraded, but not the child class? They should both be downgraded together (i.e. both should have their types removed). I don't see how |
by skipping on final class, that will loop back search for parent which parent may be cached by reflection after changed. Could you add new fixture to cover that? I don't know if that will be resolvable tho, but let's give it another try. |
https://github.com/rectorphp/rector-downgrade-php/pull/141/files I added 4 fixture tests, with all combinations:
Is this what you wanted? |
Thank you, I will check if that will be resolvable 👍 |
|
@samsonasik just for your information, I've decided to bump my downgrade's PHP version to 7.2, following Rector (rectorphp/rector-src#1955). So I won't have the issue with |
Thank you for the info, is it mean that the issue can be closed? |
Well, that's up to you, the bug is still happening... (both Rector and my project don't need to fix it anymore, but anyone else downgrading to PHP 7.1 will still experience the bug) |
Ok, I am closing it then, the possible solution I can found is to configure it like in |
Bug Report
Minimal PHP Code Causing Issue
See https://getrector.com/demo/3d9663ae-6d21-43f7-90dc-cb4439dd70a8
Responsible rules
DowngradeParameterTypeWideningRector
Expected Behavior
DowngradeParameterTypeWideningRector
is currently removing the typeInstanceManagerInterface
of the property:But this is wrong.
DowngradeParameterTypeWideningRector
should leave it as is.This error started happening with
v.0.17.2
I believe (but maybe fromv0.17.1
orv0.17.0
, as I hadn't fully tested it with those versions).The text was updated successfully, but these errors were encountered: