Add the possibility to ignore rector rules at the file level#5952
Add the possibility to ignore rector rules at the file level#5952carlos-granados wants to merge 5 commits intorectorphp:mainfrom
Conversation
| use Rector\Skipper\Contract\SkipVoterInterface; | ||
| use Rector\Skipper\Skipper\SkipSkipper; | ||
|
|
||
| final readonly class CommentSkipVoter implements SkipVoterInterface |
There was a problem hiding this comment.
use a dedicated service instead, and use on Skipper::shouldSkipCurrentNode() to avoid bc break due to new ?Node $node parameter addition.
| * @var array<class-string<SkipVoterInterface>> | ||
| */ | ||
| private const SKIP_VOTER_CLASSES = [ClassSkipVoter::class]; | ||
| private const SKIP_VOTER_CLASSES = [ClassSkipVoter::class, CommentSkipVoter::class]; |
There was a problem hiding this comment.
We add a new SkipVoter that will look at the comments for any node
| public function match(string | object $element): bool; | ||
|
|
||
| public function shouldSkip(string | object $element, string $filePath): bool; | ||
| public function shouldSkip(string | object $element, string $filePath, ?Node $node): bool; |
There was a problem hiding this comment.
We modify the SkipVoterInterface so that the node is also passed to the shouldSkip function
There was a problem hiding this comment.
That bc break, additional functionality can be added Skipper::shouldSkipCurrentNode() to avoid bc break.
There was a problem hiding this comment.
Do you mean adding this to the interface? 🤔
| } | ||
|
|
||
| public function shouldSkip(string | object $element, string $filePath): bool | ||
| public function shouldSkip(string | object $element, string $filePath, ?Node $node): bool |
There was a problem hiding this comment.
Modify the existing voter to follow the new interface
| use Rector\Skipper\Contract\SkipVoterInterface; | ||
| use Rector\Skipper\Skipper\SkipSkipper; | ||
|
|
||
| final readonly class CommentSkipVoter implements SkipVoterInterface |
There was a problem hiding this comment.
This is the new voter. It calls a new function in the SkipSkipper helper which is the one that actually checks the comments
|
|
||
| final readonly class SkipSkipper | ||
| { | ||
| private const RECTOR_IGNORE_NEXT_LINE_TAG = '@rector-ignore-next-line'; |
There was a problem hiding this comment.
These are the two tags that we expect to see in the comments
| return $this->myVariable; | ||
| } | ||
|
|
||
| // @rector-ignore AddParamTypeFromPropertyTypeRector, AddVoidReturnTypeWhereNoReturnRector |
There was a problem hiding this comment.
It should be possible to list more than one rule
| $this->myVariable = $myVariable; | ||
| } | ||
|
|
||
| // @rector-ignore AddParamTypeFromPropertyTypeRector |
There was a problem hiding this comment.
It should also be possible to have more than one comment
| } | ||
|
|
||
| /** | ||
| * @rector-ignore AddParamTypeFromPropertyTypeRector |
There was a problem hiding this comment.
Or use a comment with several lines
| $this->myVariable = $myVariable; | ||
| } | ||
|
|
||
| // @rector-ignore-next-line |
There was a problem hiding this comment.
If we use the ignore next line tag, it should ignore all rules
| $this->myVariable = $myVariable; | ||
| } | ||
|
|
||
| // @rector-ignore AddParamTypeFromPropertyTypeRector |
There was a problem hiding this comment.
If we ignore one rule, all other rules should still apply
| { | ||
| private int $myVariable; | ||
|
|
||
| // @rector-ignore NumericReturnTypeFromStrictScalarReturnsRector |
There was a problem hiding this comment.
I think this needs to be fqcn so exact class name will be validated to avoid 2 class (core vs override custom rule conflict)
There was a problem hiding this comment.
Having to use the FQCN would not be very convenient as you would end up with comments like
// @rector-ignore Rector\TypeDeclaration\Rector\ClassMethod\NumericReturnTypeFromStrictScalarReturnsRector
I tried to implement it so that you should import the class by doing something like:
use Rector\TypeDeclaration\Rector\ClassMethod\NumericReturnTypeFromStrictScalarReturnsRector;
...
// @rector-ignore NumericReturnTypeFromStrictScalarReturnsRector
My problem was then converting this to a FQCN when reading the comment so that I could compare it to the class name of the current rule. I could not find a way to do this, any pointers would be helpful
|
@samsonasik saw your comments about the BC break but not sure how to proceed here. The |
|
The new service should not implements then, use it on after this line: should be something like: -return $this->rectifiedAnalyzer->hasRectified($rectorClass, $node);
+if ($this->rectifiedAnalyzer->hasRectified($rectorClass, $node)) {
+ return true;
+}
+
+return $this->commentSkipper->shouldSkip($rectorClass, $node); |
|
@samsonasik understood now, I will work to modify this PR to follow your suggestion |
|
Btw, the similar functionality was exists with You can check the reasoning there, and if there is new proposal for it, I will let @TomasVotruba decide |
Didn't know about this. Will check it! |
|
@samsonasik added two changes:
or |
|
If docblock tag is generic, classnames can be collected from PhpDocInfo, something like this |
The problem is that we want to be able to use comments which are not docblocks and these do not get parsed in the same way |
|
The generic is something like |
|
Hi @carlos-granados , thanks for patience and appologies for my late reply. Using dev tool configuration in code seems like a wrong design. That's why I removed it in the past: #5952 (comment) Code Sniffer/PHPStan have such a feature, but it doesn't bring any new value to the tool. In practise, it also makes false positive ignored hard to spot, as part of the code. We often have to go through it one by one and check, and check if still valid. PHPStan reports such cases, but Rector does not. It would also cost us a performance hit. Having one place to ignore errors is the best design choice, as there place of least surprise. We avoid cases like "oh, we forgot to check every file for the docblock and that's why this upgrade rule was missed". Another problem is, that when we had such a feature, it was used as "ignore every rule", only because it was easy and possible. That's why I'm rejecting this feature. Thanks for understanding 🙏 |
|
No problem, thanks for the great explanation. And, in any case, creating
this PR has allowed me to learn more about Rector, which is always good 😊
…On Mon, 17 Jun 2024, 05:25 Tomas Votruba, ***@***.***> wrote:
Hi @carlos-granados <https://github.com/carlos-granados> , thanks for
patience and appologies for my late reply.
I took a time to think about this deeply and was distracted by other work
and open-source.
Using dev tool configuration in code seems like a wrong design. Code
Sniffer/PHPStan have such a feature, but it didn't bring any new value to
the tool. In practise, it also makes false positive ignored hard to spot,
as part of the code. We often have to go through it one by one and check,
and check if still valid. PHPStan reports such cases, but Rector does not.
It would also cost us a performance hit.
Having one place to ignore errors is the best design choice, as there
place of least surprise. We avoid cases like "oh, we forgot to check every
file for the docblock and that's why this upgrade rule was missed". Another
problem is, that when we had such a feature, it was used as "ignore every
rule", only because it was easy and possible.
That's why I'm rejecting this feature.
Thanks for understanding 🙏
—
Reply to this email directly, view it on GitHub
<#5952 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAKRVQW6XSWERRAGSVO6QMTZH2TQBAVCNFSM6AAAAABI6W6CRWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNZSHA2TGMBSG4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
|
If anyone else is interested in this option, it is available in this fork: https://github.com/carlos-granados/rector |
Currently it is possible to skip a file or list of files when applying rector rules and it is also possible to skip a particular rule. You can also skip a particular rule for a file or a list of files. But it is not possible to skip a single case of applying a rule in a file without also skipping all the other cases of that rule in that file.
This PR follows a similar solution implemented by PHPStan with their
@phpstan-ignoreand@phpstan-ignore-next-linetags and implements two comment tags:@rector-ignore-next-linewill let you skip any rector rule that might be applied to the node defined in the next line@rector-ignore RULE_NAMEwill let you skip any particular rector rule that might be applied to the node defined in the next line.RULE_NAMEneeds to be the name of the class for that particular rule (for exampleNumericReturnTypeFromStrictScalarReturnsRector) without a namespace. If you want to skip more than one rule you can list them separated with commasIncludes a test for the new functionality, see the comments in the PR for more info