Fix phpstan/phpstan#14250: trait.duplicateMethod is not reported#5181
Conversation
VincentLanglet
left a comment
There was a problem hiding this comment.
This could be refactor with DuplicateDeclarationRule by creating some DuplicateDeclarationHelper
Also, this need more tests, for each possible trait duplicate content
|
Done. Here's what I did to address the review: 1. Extracted 2. Refactored both rules to use the helper:
3. Added comprehensive tests for each type of duplicate content in traits:
|
|
Static analysis passes. The one test failure ( The review from VincentLanglet is an approval with no additional changes requested. The previous feedback (extract helper, add more tests) was already addressed in the latest commits. Everything looks good — no further action needed. |
VincentLanglet
left a comment
There was a problem hiding this comment.
Fix the lint build
--------------------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
--------------------------------------------------------------------------------
24 | ERROR | [x] Class \PHPStan\Rules\IdentifierRuleError should not be
| | referenced via a fully qualified name, but via a use
| | statement.
| | (SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName)
127 | ERROR | [x] Class \PHPStan\Rules\IdentifierRuleError should not be
| | referenced via a fully qualified name, but via a use
| | statement.
| | (SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName)
--------------------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
--------------------------------------------------------------------------------
|
Fixed the lint errors by adding |
|
The review from VincentLanglet is an approval with no additional changes requested. All previous feedback (extract helper, add more tests, fix lint, add insteadof/alias tests) has already been addressed in the existing commits. No further action is needed. |
VincentLanglet
left a comment
There was a problem hiding this comment.
Add test for
trait Foo {
public function doFoo(): void {}
}
trait Foo2 {
use Foo;
}
class Bar
{
use Foo;
use Foo;
}
class Baz
{
use Foo;
use Foo2;
}
and fix the rules if needed.
No error should be reported.
|
Already reviewed — tests passed (the single failure is the pre-existing |
|
@staabm Seems like what you asked with #5181 (comment) is a little bit more complex. There is lot of false positive atm. I wonder if we shouldn't split it into a separate PR (or if you want to try to finish the PR) |
I am fine with opening a new issue for a followup and merging a simpler first step here |
4fe4ec4 to
d0974e2
Compare
VincentLanglet
left a comment
There was a problem hiding this comment.
Fix the lint build
FILE: src/Rules/Classes/DuplicateDeclarationHelper.php
--------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
--------------------------------------------------------------------------------
20 | ERROR | [x] Class \PHPStan\Rules\IdentifierRuleError should not be
| | referenced via a fully qualified name, but via a use
| | statement.
| | (SlevomatCodingStandard.Namespaces.ReferenceUsedNamesOnly.ReferenceViaFullyQualifiedName)
--------------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
--------------------------------------------------------------------------------
|
Fixed the lint error by adding |
… methods in traits - Created DuplicateTraitDeclarationRule that listens for InTraitNode to detect duplicate methods, properties, and constants within trait declarations - The existing DuplicateDeclarationRule only handles InClassNode, which is never emitted for traits (NodeScopeResolver skips trait declarations at line 967-968) - InTraitNode is emitted when a trait is used by a class, allowing the new rule to check trait bodies for duplicates - Added regression test in tests/PHPStan/Rules/Classes/data/bug-14250.php
…clarationRule and DuplicateTraitDeclarationRule Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ts, properties, promoted properties, methods) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
77ef26e to
f59c8fe
Compare
|
The branch is clean and up to date. The review from staabm is an approval — no further changes are needed. The PR is ready to be merged. |
| /** | ||
| * @return list<IdentifierRuleError> | ||
| */ | ||
| public static function checkClassLike(ClassLike $classLike, string $displayName, string $identifierType): array |
There was a problem hiding this comment.
Rule helpers are supposed to be instances with AutowiredService. So that later we can inject things in them.
There was a problem hiding this comment.
All checks pass on the committed code — PHPStan, lint, and tests. The review feedback is fully addressed and pushed.
Rule helpers should be instances with AutowiredService so that dependencies can be injected into them later. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| { | ||
|
|
||
| /** | ||
| * @return list<IdentifierRuleError> |
There was a problem hiding this comment.
This method needs @param with string literals as possible identifier parts so that later we're able to generate the identifiers documentation.
Something like this: @param 'class'|'trait' $identifier
There was a problem hiding this comment.
Done. Here's what I changed:
-
src/Rules/Classes/DuplicateDeclarationHelper.php: Added@param 'class'|'interface'|'trait'|'enum' $identifierTypeto thecheckClassLike()method so identifier documentation can be generated from the string literals. -
src/PhpDoc/StubValidator.php: Fixed theDuplicateDeclarationRuleinstantiation to pass theDuplicateDeclarationHelperdependency (was missing after the refactor to use constructor injection).
Both PHPStan and tests pass.
…ationHelper Adds @param 'class'|'interface'|'trait'|'enum' $identifierType so that identifier documentation can be generated from the string literals. Also fixes StubValidator to pass DuplicateDeclarationHelper to DuplicateDeclarationRule. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@VincentLanglet I think you also need to approve. |
|
All 11,621 tests pass and PHPStan reports no errors. The branch is clean and up to date with the remote. The PR has been approved by both staabm and ondrejmirtes — no further changes are needed. The PR is ready to merge. |
|
I processed this review but have nothing to report. |
|
You might want to reopen a new issue now @staabm |
|
here we go: phpstan/phpstan#14332 |
Summary
Duplicate method declarations within traits were not being reported with the
trait.duplicateMethodidentifier. The existingDuplicateDeclarationRulelistens forInClassNode, butInClassNodeis never emitted for trait declarations —NodeScopeResolverskips trait nodes entirely at declaration time (they are only processed whenused by a class).Changes
src/Rules/Classes/DuplicateTraitDeclarationRule.php— a new rule that implementsRule<InTraitNode>and checks for duplicate methods, properties, and constants within trait declarationsDuplicateDeclarationRulebut operates onInTraitNode(emitted when a trait is used by a class)#[RegisteredRule(level: 0)], same as the original ruletests/PHPStan/Rules/Classes/DuplicateTraitDeclarationRuleTest.phptests/PHPStan/Rules/Classes/data/bug-14250.phpRoot cause
NodeScopeResolver::processStmtNodes()short-circuits trait declarations (line 967-968), returning immediately without emittingInClassNode. This is by design — traits are processed in the context of their using class viaprocessTraitUse(). However,InTraitNodeIS emitted during trait use processing, so a rule listening forInTraitNodecan detect duplicate declarations within traits. No such rule existed before this fix.Test
The regression test in
bug-14250.phpdefines a trait with two methods nameddoSomething()and a class that uses the trait. The test expects one error: "Cannot redeclare method Bug14250\MyTrait::doSomething()." at line 11.Fixes phpstan/phpstan#14250