From c6035f3ca1511332c9fec762135a24f5963dee06 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 3 Jul 2023 15:07:05 +0200 Subject: [PATCH] Fix processing traits with renamed methods --- phpstan-baseline.neon | 2 +- src/Analyser/NodeScopeResolver.php | 22 ++++++++--- .../Rules/Properties/data/bug-7198.php | 37 +++++++++++++++++++ 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 03bf364495..7ab883dfed 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -848,7 +848,7 @@ parameters: - message: "#^Doing instanceof PHPStan\\\\Type\\\\ConstantScalarType is error\\-prone and deprecated\\. Use Type\\:\\:isConstantScalarValue\\(\\) or Type\\:\\:getConstantScalarTypes\\(\\) or Type\\:\\:getConstantScalarValues\\(\\) instead\\.$#" - count: 2 + count: 4 path: src/Type/Constant/ConstantBooleanType.php - diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index c56e2198c4..60e8e61279 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -4293,16 +4293,22 @@ private function processNodesForTraitUse($node, ClassReflection $traitReflection if ($node instanceof Node) { if ($node instanceof Node\Stmt\Trait_ && $traitReflection->getName() === (string) $node->namespacedName && $traitReflection->getNativeReflection()->getStartLine() === $node->getStartLine()) { $methodModifiers = []; + $methodNames = []; foreach ($adaptations as $adaptation) { if (!$adaptation instanceof Node\Stmt\TraitUseAdaptation\Alias) { continue; } - if ($adaptation->newModifier === null) { + $methodName = $adaptation->method->toLowerString(); + if ($adaptation->newModifier !== null) { + $methodModifiers[$methodName] = $adaptation->newModifier; + } + + if ($adaptation->newName === null) { continue; } - $methodModifiers[$adaptation->method->toLowerString()] = $adaptation->newModifier; + $methodNames[$methodName] = $adaptation->newName; } $stmts = $node->stmts; @@ -4311,13 +4317,17 @@ private function processNodesForTraitUse($node, ClassReflection $traitReflection continue; } $methodName = $stmt->name->toLowerString(); - if (!array_key_exists($methodName, $methodModifiers)) { + $methodAst = clone $stmt; + $stmts[$i] = $methodAst; + if (array_key_exists($methodName, $methodModifiers)) { + $methodAst->flags = ($methodAst->flags & ~ Node\Stmt\Class_::VISIBILITY_MODIFIER_MASK) | $methodModifiers[$methodName]; + } + + if (!array_key_exists($methodName, $methodNames)) { continue; } - $methodAst = clone $stmt; - $methodAst->flags = ($methodAst->flags & ~ Node\Stmt\Class_::VISIBILITY_MODIFIER_MASK) | $methodModifiers[$methodName]; - $stmts[$i] = $methodAst; + $methodAst->name = $methodNames[$methodName]; } $this->processStmtNodes($node, $stmts, $scope->enterTrait($traitReflection), $nodeCallback, StatementContext::createTopLevel()); return; diff --git a/tests/PHPStan/Rules/Properties/data/bug-7198.php b/tests/PHPStan/Rules/Properties/data/bug-7198.php index 5150b8fb97..75d9ab0af5 100644 --- a/tests/PHPStan/Rules/Properties/data/bug-7198.php +++ b/tests/PHPStan/Rules/Properties/data/bug-7198.php @@ -49,3 +49,40 @@ public function foo(): void $this->callee->foo(); } } + +trait Identifiable +{ + public readonly int $id; + + public function __construct() + { + $this->id = rand(); + } +} + +trait CreateAware +{ + public readonly \DateTimeImmutable $createdAt; + + public function __construct() + { + $this->createdAt = new \DateTimeImmutable(); + } +} + +abstract class Entity +{ + use Identifiable { + Identifiable::__construct as private __identifiableConstruct; + } + + use CreateAware { + CreateAware::__construct as private __createAwareConstruct; + } + + public function __construct() + { + $this->__identifiableConstruct(); + $this->__createAwareConstruct(); + } +}