mirror of
https://github.com/rectorphp/rector.git
synced 2024-06-01 17:00:51 +00:00
[Php81] Skip ReadOnlyPropertyRector on Clone $this (#1599)
* add failing test for cloned properties Signed-off-by: Gary Lockett <gary@creativecow.uk> * [Php81] Skip ReadOnlyPropertyRector on Clone $this * final touch: ensure name is equal * final touch: ensure use TypeWithClassName with check class name is equal * phpstan * flip if to reduce deep if * final touch: early check name not equals, then check type * comment * comment * comment * comment * final touch: re-use found Class_ Co-authored-by: Gary Lockett <gary@creativecow.uk>
This commit is contained in:
parent
bc09bdc203
commit
311ffc6ec3
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Tests\Php81\Rector\Property\ReadOnlyPropertyRector\Fixture;
|
||||
|
||||
final class SkipWriteAlsoClonedProperty
|
||||
{
|
||||
private string $name;
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
public function withName(string $name): self
|
||||
{
|
||||
$clone = clone $this;
|
||||
$clone->name = $name;
|
||||
|
||||
return $clone;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
|
@ -11,11 +11,13 @@ use PhpParser\Node\Stmt;
|
|||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassLike;
|
||||
use PhpParser\Node\Stmt\Property;
|
||||
use PHPStan\Type\TypeWithClassName;
|
||||
use Rector\Core\Enum\ObjectReference;
|
||||
use Rector\Core\PhpParser\AstResolver;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\Reflection\ReflectionResolver;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
||||
final class PropertyFetchFinder
|
||||
{
|
||||
|
@ -29,6 +31,7 @@ final class PropertyFetchFinder
|
|||
private readonly NodeNameResolver $nodeNameResolver,
|
||||
private readonly ReflectionResolver $reflectionResolver,
|
||||
private readonly AstResolver $astResolver,
|
||||
private readonly NodeTypeResolver $nodeTypeResolver
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -118,7 +121,7 @@ final class PropertyFetchFinder
|
|||
return false;
|
||||
}
|
||||
|
||||
return $this->isNamePropertyNameEquals($propertyFetch, $propertyName);
|
||||
return $this->isNamePropertyNameEquals($propertyFetch, $propertyName, $class);
|
||||
});
|
||||
|
||||
/** @var StaticPropertyFetch[] $staticPropertyFetches */
|
||||
|
@ -146,13 +149,27 @@ final class PropertyFetchFinder
|
|||
return $parent !== $class && ! $hasTrait;
|
||||
}
|
||||
|
||||
private function isNamePropertyNameEquals(PropertyFetch $propertyFetch, string $propertyName): bool
|
||||
private function isNamePropertyNameEquals(PropertyFetch $propertyFetch, string $propertyName, Class_ $class): bool
|
||||
{
|
||||
if (! $this->nodeNameResolver->isName($propertyFetch->var, self::THIS)) {
|
||||
// early check if property fetch name is not equals with property name
|
||||
// so next check is check var name and var type only
|
||||
if (! $this->nodeNameResolver->isName($propertyFetch->name, $propertyName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->nodeNameResolver->isName($propertyFetch->name, $propertyName);
|
||||
if ($this->nodeNameResolver->isName($propertyFetch->var, self::THIS)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$propertyFetchVarType = $this->nodeTypeResolver->getType($propertyFetch->var);
|
||||
if (! $propertyFetchVarType instanceof TypeWithClassName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$propertyFetchVarTypeClassName = $propertyFetchVarType->getClassName();
|
||||
$classLikeName = $this->nodeNameResolver->getName($class);
|
||||
|
||||
return $propertyFetchVarTypeClassName === $classLikeName;
|
||||
}
|
||||
|
||||
private function resolvePropertyName(Property | Param $propertyOrPromotedParam): ?string
|
||||
|
|
Loading…
Reference in New Issue
Block a user