Move from CLASS_NODE attribute to more reliable parent node finder (#1162)

This commit is contained in:
Tomas Votruba 2021-11-06 12:52:18 +01:00 committed by GitHub
parent e46fe290d8
commit c3b6efea7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 329 additions and 337 deletions

View File

@ -47,7 +47,6 @@ expectedArguments(
\PhpParser\Node::getAttribute(),
0,
\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE,
\Rector\NodeTypeResolver\Node\AttributeKey::CLASS_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::CLASS_NAME,
\Rector\NodeTypeResolver\Node\AttributeKey::METHOD_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE,
@ -73,7 +72,6 @@ expectedArguments(
\PhpParser\Node::setAttribute(),
0,
\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE,
\Rector\NodeTypeResolver\Node\AttributeKey::CLASS_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::CLASS_NAME,
\Rector\NodeTypeResolver\Node\AttributeKey::METHOD_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE,

View File

@ -43,7 +43,7 @@ foreach ($fileInfos as $fileInfo) {
### 2.1 Prepare Phase
- Files are parsed by [`nikic/php-parser`](https://github.com/nikic/PHP-Parser), 4.0 that supports writing modified tree back to a file
- Then nodes (array of objects by parser) are traversed by `StandaloneTraverseNodeTraverser` to prepare their metadata, e.g. the class name, the method node the node is in, the namespace name etc. added by `$node->setAttribute(Attribute::CLASS_NODE, 'value')`.
- Then nodes (array of objects by parser) are traversed by `StandaloneTraverseNodeTraverser` to prepare their metadata, e.g. the class name, the method node the node is in, the namespace name etc. added by `$node->setAttribute('key', 'value')`.
### 2.2 Rectify Phase

View File

@ -24,7 +24,7 @@
"phpstan/phpstan-phpunit": "^1.0",
"rector/extension-installer": "^0.11.1",
"rector/rector-cakephp": "^0.11.6",
"rector/rector-doctrine": "^0.11.26",
"rector/rector-doctrine": "^0.11",
"rector/rector-laravel": "^0.11.8",
"rector/rector-nette": "^0.11.39",
"rector/rector-phpoffice": "^0.11.6",

View File

@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Rector\NodeTypeResolver\Node;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Symplify\SmartFileSystem\SmartFileInfo;
/**
@ -28,11 +30,18 @@ final class AttributeKey
public const USE_NODES = 'useNodes';
/**
* @deprecated Use
* @see BetterNodeFinder and
* @see NodeNameResolver to find your parent nodes.
*
* @var string
*/
public const CLASS_NAME = 'className';
/**
* @deprecated Use
* @see BetterNodeFinder to find your parent nodes.
*
* @var string
*/
public const CLASS_NODE = 'class_node';

View File

@ -39,6 +39,7 @@ use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
use Rector\Core\Configuration\RenamedClassesDataCollector;
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeCorrector\AccessoryNonEmptyStringTypeCorrector;
@ -71,6 +72,7 @@ final class NodeTypeResolver
private AccessoryNonEmptyStringTypeCorrector $accessoryNonEmptyStringTypeCorrector,
private IdentifierTypeResolver $identifierTypeResolver,
private RenamedClassesDataCollector $renamedClassesDataCollector,
private BetterNodeFinder $betterNodeFinder,
array $nodeTypeResolvers
) {
foreach ($nodeTypeResolvers as $nodeTypeResolver) {
@ -324,12 +326,12 @@ final class NodeTypeResolver
return $this->isObjectType($node->class, $objectType);
}
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $class instanceof Class_) {
return false;
}
return $this->isObjectType($classLike, $objectType);
return $this->isObjectType($class, $objectType);
}
private function isUnionTypeable(Type $first, Type $second): bool

View File

@ -11,8 +11,8 @@ use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\ObjectWithoutClassType;
use PHPStan\Type\Type;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Symfony\Contracts\Service\Attribute\Required;
@ -20,6 +20,11 @@ final class ClassMethodOrClassConstTypeResolver implements NodeTypeResolverInter
{
private NodeTypeResolver $nodeTypeResolver;
public function __construct(
private BetterNodeFinder $betterNodeFinder
) {
}
#[Required]
public function autowireClassMethodOrClassConstTypeResolver(NodeTypeResolver $nodeTypeResolver): void
{
@ -39,7 +44,7 @@ final class ClassMethodOrClassConstTypeResolver implements NodeTypeResolverInter
*/
public function resolve(Node $node): Type
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
if (! $classLike instanceof ClassLike) {
// anonymous class
return new ObjectWithoutClassType();

View File

@ -12,6 +12,7 @@ use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -27,7 +28,8 @@ final class PropertyFetchTypeResolver implements NodeTypeResolverInterface
public function __construct(
private NodeNameResolver $nodeNameResolver,
private ReflectionProvider $reflectionProvider
private ReflectionProvider $reflectionProvider,
private BetterNodeFinder $betterNodeFinder
) {
}
@ -56,13 +58,13 @@ final class PropertyFetchTypeResolver implements NodeTypeResolverInterface
return $vendorPropertyType;
}
/** @var Scope|null $scope */
$scope = $node->getAttribute(AttributeKey::SCOPE);
if (! $scope instanceof Scope) {
$classNode = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
// fallback to class, since property fetches are not scoped by PHPStan
if ($classNode instanceof ClassLike) {
$scope = $classNode->getAttribute(AttributeKey::SCOPE);
if ($classLike instanceof ClassLike) {
$scope = $classLike->getAttribute(AttributeKey::SCOPE);
}
if (! $scope instanceof Scope) {

View File

@ -70,7 +70,6 @@ final class FunctionMethodAndClassNodeVisitor extends NodeVisitorAbstract
$this->setClassNodeAndName($node);
}
$node->setAttribute(AttributeKey::CLASS_NODE, $this->classLike);
$node->setAttribute(AttributeKey::CLASS_NAME, $this->className);
}

View File

@ -8,9 +8,8 @@ use PhpParser\Node;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Trait_;
use PHPStan\Type\Accessory\HasOffsetType;
use PHPStan\Type\Accessory\NonEmptyArrayType;
use PHPStan\Type\ArrayType;
@ -19,8 +18,8 @@ use PHPStan\Type\MixedType;
use PHPStan\Type\ThisType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeCorrector\PregMatchTypeCorrector;
use Rector\NodeTypeResolver\NodeTypeResolver;
@ -29,7 +28,8 @@ final class ArrayTypeAnalyzer
public function __construct(
private NodeNameResolver $nodeNameResolver,
private NodeTypeResolver $nodeTypeResolver,
private PregMatchTypeCorrector $pregMatchTypeCorrector
private PregMatchTypeCorrector $pregMatchTypeCorrector,
private BetterNodeFinder $betterNodeFinder,
) {
}
@ -96,13 +96,12 @@ final class ArrayTypeAnalyzer
return false;
}
/** @var Class_|Trait_|Interface_|null $classLike */
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
if ($classLike instanceof Interface_) {
return false;
}
if ($classLike === null) {
if (! $classLike instanceof ClassLike) {
return false;
}

View File

@ -8,9 +8,9 @@ use PhpParser\Node;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\NodeFinder\PropertyFetchFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\ReadWrite\Contract\ReadNodeAnalyzerInterface;
final class LocalPropertyFetchReadNodeAnalyzer implements ReadNodeAnalyzerInterface
@ -18,7 +18,8 @@ final class LocalPropertyFetchReadNodeAnalyzer implements ReadNodeAnalyzerInterf
public function __construct(
private JustReadExprAnalyzer $justReadExprAnalyzer,
private PropertyFetchFinder $propertyFetchFinder,
private NodeNameResolver $nodeNameResolver
private NodeNameResolver $nodeNameResolver,
private BetterNodeFinder $betterNodeFinder
) {
}
@ -32,7 +33,7 @@ final class LocalPropertyFetchReadNodeAnalyzer implements ReadNodeAnalyzerInterf
*/
public function isRead(Node $node): bool
{
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $class instanceof Class_) {
// assume worse to keep node protected
return true;

View File

@ -14,6 +14,7 @@ use PHPStan\Type\Generic\TemplateTypeMap;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\StaticTypeMapper\StaticTypeMapper;
use Symfony\Contracts\Service\Attribute\Required;
@ -27,15 +28,19 @@ final class NameScopeFactory
private PhpDocInfoFactory $phpDocInfoFactory;
private BetterNodeFinder $betterNodeFinder;
// This is needed to avoid circular references
#[Required]
public function autowireNameScopeFactory(
PhpDocInfoFactory $phpDocInfoFactory,
StaticTypeMapper $staticTypeMapper
StaticTypeMapper $staticTypeMapper,
BetterNodeFinder $betterNodeFinder,
): void {
$this->phpDocInfoFactory = $phpDocInfoFactory;
$this->staticTypeMapper = $staticTypeMapper;
$this->betterNodeFinder = $betterNodeFinder;
}
public function createNameScopeFromNodeWithoutTemplateTypes(Node $node): NameScope
@ -104,10 +109,11 @@ final class NameScopeFactory
{
$nodeTemplateTypes = $this->resolveTemplateTypesFromNode($node);
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
$classTemplateTypes = [];
if ($class instanceof ClassLike) {
$classTemplateTypes = $this->resolveTemplateTypesFromNode($class);
if ($classLike instanceof ClassLike) {
$classTemplateTypes = $this->resolveTemplateTypesFromNode($classLike);
}
$templateTypes = array_merge($nodeTemplateTypes, $classTemplateTypes);

View File

@ -79,7 +79,7 @@ parameters:
- '#Cognitive complexity for "Rector\\Php80\\NodeResolver\\SwitchExprsResolver\:\:resolve\(\)" is (.*?), keep it under 9#'
-
message: "#^Cognitive complexity for \"Rector\\\\PhpSpecToPHPUnit\\\\Rector\\\\MethodCall\\\\PhpSpecPromisesToPHPUnitAssertRector\\:\\:refactor\\(\\)\" is 13, keep it under 9$#"
message: "#^Cognitive complexity for \"Rector\\\\PhpSpecToPHPUnit\\\\Rector\\\\MethodCall\\\\PhpSpecPromisesToPHPUnitAssertRector\\:\\:refactor\\(\\)\" is (.*?), keep it under 9$#"
path: rules/PhpSpecToPHPUnit/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php
-

View File

@ -1,28 +0,0 @@
<?php
namespace Rector\Tests\DeadCode\Rector\Property\RemoveUnusedPrivatePropertyRector\Fixture;
use PhpParser\Node;
use PhpParser\Node\Stmt\ClassLike;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class SkipArrayPop
{
/**
* @var ClassLike[]|null[]
*/
private $classStack = [];
private $classLike;
public function leaveNode(Node $node)
{
$classLike = array_pop($this->classStack);
$node->setAttribute(AttributeKey::CLASS_NODE, $classLike);
}
public function processClass(Node $node): void
{
$this->classStack[] = $this->classLike;
}
}

View File

@ -1,43 +0,0 @@
<?php
namespace Rector\Tests\Php74\Rector\Property\TypedPropertyRector\Fixture;
trait JsonBodyTrait
{
private $body;
public function setJsonBody(array $body): self
{
$this->body = $body;
return $this;
}
public function getJsonBody(): ?array
{
return $this->body;
}
}
?>
-----
<?php
namespace Rector\Tests\Php74\Rector\Property\TypedPropertyRector\Fixture;
trait JsonBodyTrait
{
private ?array $body = null;
public function setJsonBody(array $body): self
{
$this->body = $body;
return $this;
}
public function getJsonBody(): ?array
{
return $this->body;
}
}
?>

View File

@ -0,0 +1,19 @@
<?php
namespace Rector\Tests\Php74\Rector\Property\TypedPropertyRector\Fixture;
trait SkipTrait
{
private $body;
public function setJsonBody(array $body): self
{
$this->body = $body;
return $this;
}
public function getJsonBody(): ?array
{
return $this->body;
}
}

View File

@ -10,7 +10,6 @@ trait MaterializedPathEntity
public function setParent(self $parent = null) : static
{
$this->parent = $parent;
return $this;
}

View File

@ -23,7 +23,6 @@ use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Enum\ObjectReference;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -150,11 +149,7 @@ CODE_SAMPLE
return $this->isObjectType($node->class, $objectType);
}
// ClassMethod
/** @var Class_|null $classLike */
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
// anonymous class
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return false;
}

View File

@ -21,7 +21,6 @@ use PHPStan\Type\NullType;
use PHPStan\Type\Type;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PHPStan\Type\StaticTypeAnalyzer;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@ -170,7 +169,7 @@ CODE_SAMPLE
private function resolvePropertyFetchType(PropertyFetch $propertyFetch): Type
{
$classLike = $propertyFetch->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($propertyFetch, Class_::class);
if (! $classLike instanceof Class_) {
return new MixedType();
}

View File

@ -10,7 +10,6 @@ use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\Enum\ObjectReference;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -62,7 +61,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $class instanceof Class_) {
return null;
}

View File

@ -155,7 +155,8 @@ CODE_SAMPLE
return false;
}
$classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
$classLike = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
if (! $classLike instanceof Class_) {
return false;
}

View File

@ -36,7 +36,7 @@ final class IsClassMethodUsedAnalyzer
public function isClassMethodUsed(ClassMethod $classMethod): bool
{
$class = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
if (! $class instanceof Class_) {
return true;
}

View File

@ -8,14 +8,15 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ControllerClassMethodManipulator
{
public function __construct(
private NodeNameResolver $nodeNameResolver,
private PhpDocInfoFactory $phpDocInfoFactory
private PhpDocInfoFactory $phpDocInfoFactory,
private BetterNodeFinder $betterNodeFinder,
) {
}
@ -35,12 +36,12 @@ final class ControllerClassMethodManipulator
return false;
}
$classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
if (! $class instanceof Class_) {
return false;
}
return $this->hasParentClassController($classLike);
return $this->hasParentClassController($class);
}
private function hasParentClassController(Class_ $class): bool

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Rector\DeadCode\PhpDoc;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Trait_;
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
use PHPStan\PhpDocParser\Ast\Type\GenericTypeNode;
@ -12,13 +13,14 @@ use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
use PHPStan\PhpDocParser\Ast\Type\ThisTypeNode;
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
use Rector\BetterPhpDocParser\ValueObject\Type\SpacingAwareCallableTypeNode;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
final class DeadReturnTagValueNodeAnalyzer
{
public function __construct(
private TypeComparator $typeComparator
private TypeComparator $typeComparator,
private BetterNodeFinder $betterNodeFinder,
) {
}
@ -29,7 +31,7 @@ final class DeadReturnTagValueNodeAnalyzer
return false;
}
$classLike = $functionLike->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($functionLike, ClassLike::class);
if ($classLike instanceof Trait_ && $returnTagValueNode->type instanceof ThisTypeNode) {
return false;
}

View File

@ -11,7 +11,6 @@ use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\NodeManipulator\ClassMethodManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -60,7 +59,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -14,7 +14,6 @@ use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\Rector\AbstractRector;
use Rector\DeadCode\Comparator\CurrentAndParentClassMethodComparator;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -82,7 +81,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if ($this->shouldSkipClass($classLike)) {
return null;
}

View File

@ -12,7 +12,6 @@ use Rector\Core\NodeManipulator\ClassMethodManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\DeadCode\NodeManipulator\ControllerClassMethodManipulator;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -65,7 +64,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}
@ -131,7 +130,7 @@ CODE_SAMPLE
}
if ($this->nodeNameResolver->isName($classMethod, MethodName::CONSTRUCT)) {
$class = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
return $class instanceof Class_ && $class->extends instanceof FullyQualified;
}

View File

@ -5,12 +5,11 @@ declare(strict_types=1);
namespace Rector\DeadCode\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Interface_;
use Rector\Core\NodeAnalyzer\ParamAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -81,8 +80,8 @@ CODE_SAMPLE
return null;
}
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
if ($classLike instanceof Interface_) {
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $class instanceof Class_) {
return null;
}

View File

@ -134,7 +134,7 @@ CODE_SAMPLE
private function hasDynamicMethodCallOnFetchThis(ClassMethod $classMethod): bool
{
$class = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
if (! $class instanceof Class_) {
return false;
}

View File

@ -13,7 +13,6 @@ use Rector\Core\PhpParser\NodeFinder\PropertyFetchFinder;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -87,7 +86,7 @@ CODE_SAMPLE
return null;
}
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $class instanceof Class_) {
return null;
}

View File

@ -184,7 +184,7 @@ CODE_SAMPLE
/** @var PropertyFetch|StaticPropertyFetch $propertyFetch */
$propertyFetch = $expr;
$classLike = $propertyFetch->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($propertyFetch, Class_::class);
if (! $classLike instanceof Class_) {
return true;
@ -217,7 +217,7 @@ CODE_SAMPLE
return false;
}
$classLike = $expr->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($expr, Class_::class);
if (! $classLike instanceof Class_) {
return false;
}

View File

@ -14,7 +14,6 @@ use PHPStan\Type\ObjectType;
use Rector\Core\NodeManipulator\IfManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\DeadCode\FeatureSupport\FunctionSupportResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -113,7 +112,7 @@ CODE_SAMPLE
private function shouldSkip(If_ $if): bool
{
$classLike = $if->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($if, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return false;
}

View File

@ -11,6 +11,7 @@ use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
@ -92,7 +93,7 @@ CODE_SAMPLE
}
$classLike = $this->reflectionAstResolver->resolveClassFromObjectType($type);
if ($classLike === null) {
if (! $classLike instanceof ClassLike) {
return null;
}
@ -165,7 +166,7 @@ CODE_SAMPLE
return true;
}
$class = $methodCall->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($methodCall, Class_::class);
if (! $class instanceof Class_) {
return false;
}

View File

@ -74,7 +74,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -12,8 +12,8 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\PropertyToAddCollector;
use Rector\PostRector\ValueObject\PropertyMetadata;
@ -24,7 +24,8 @@ final class PropertyConstructorInjectionManipulator
private PhpDocInfoFactory $phpDocInfoFactory,
private PhpDocTypeChanger $phpDocTypeChanger,
private PhpDocTagRemover $phpDocTagRemover,
private PropertyToAddCollector $propertyToAddCollector
private PropertyToAddCollector $propertyToAddCollector,
private BetterNodeFinder $betterNodeFinder,
) {
}
@ -39,12 +40,12 @@ final class PropertyConstructorInjectionManipulator
$this->phpDocTypeChanger->changeVarType($phpDocInfo, $type);
$this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $doctrineAnnotationTagValueNode);
$classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($property, Class_::class);
if (! $class instanceof Class_) {
throw new ShouldNotHappenException();
}
$propertyMetadata = new PropertyMetadata($propertyName, $type, $property->flags);
$this->propertyToAddCollector->addPropertyToClass($classLike, $propertyMetadata);
$this->propertyToAddCollector->addPropertyToClass($class, $propertyMetadata);
}
}

View File

@ -84,7 +84,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return null;
}

View File

@ -6,6 +6,7 @@ namespace Rector\DowngradePhp72\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Reflection\ClassReflection;
use PHPStan\Reflection\ReflectionProvider;
@ -15,7 +16,6 @@ use Rector\DowngradePhp72\NodeAnalyzer\BuiltInMethodAnalyzer;
use Rector\DowngradePhp72\NodeAnalyzer\OverrideFromAnonymousClassMethodAnalyzer;
use Rector\DowngradePhp72\NodeAnalyzer\SealedClassAnalyzer;
use Rector\DowngradePhp72\PhpDoc\NativeParamToPhpDocDecorator;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\TypeDeclaration\NodeAnalyzer\AutowiredClassMethodOrPropertyAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -115,8 +115,8 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
if ($classLike === null) {
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return null;
}

View File

@ -6,9 +6,9 @@ namespace Rector\Naming\ValueObjectFactory;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Property;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Naming\ValueObject\PropertyRename;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
* @see \Rector\Tests\Naming\ValueObjectFactory\PropertyRenameFactory\PropertyRenameFactoryTest
@ -16,7 +16,8 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
final class PropertyRenameFactory
{
public function __construct(
private NodeNameResolver $nodeNameResolver
private NodeNameResolver $nodeNameResolver,
private BetterNodeFinder $betterNodeFinder,
) {
}
@ -24,13 +25,13 @@ final class PropertyRenameFactory
{
$currentName = $this->nodeNameResolver->getName($property);
$propertyClassLike = $property->getAttribute(AttributeKey::CLASS_NODE);
if (! $propertyClassLike instanceof ClassLike) {
$classLike = $this->betterNodeFinder->findParentType($property, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return null;
}
$propertyClassLikeName = $property->getAttribute(AttributeKey::CLASS_NAME);
if ($propertyClassLikeName === null) {
$className = $this->nodeNameResolver->getName($classLike);
if (! is_string($className)) {
return null;
}
@ -38,8 +39,8 @@ final class PropertyRenameFactory
$property,
$expectedName,
$currentName,
$propertyClassLike,
$propertyClassLikeName,
$classLike,
$className,
$property->props[0]
);
}

View File

@ -87,7 +87,7 @@ CODE_SAMPLE
return null;
}
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -123,7 +123,7 @@ CODE_SAMPLE
private function resolveClassSelf(MethodCall $methodCall): ObjectReference
{
$classLike = $methodCall->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($methodCall, Class_::class);
if (! $classLike instanceof Class_) {
return ObjectReference::STATIC();
}

View File

@ -165,8 +165,8 @@ CODE_SAMPLE
}
// skip node in trait, as impossible to analyse
$classLike = $funcCall->getAttribute(AttributeKey::CLASS_NODE);
return $classLike instanceof Trait_;
$trait = $this->betterNodeFinder->findParentType($funcCall, Trait_::class);
return $trait instanceof Trait_;
}
private function castToArray(Expr $countedExpr, FuncCall $funcCall): FuncCall

View File

@ -122,7 +122,7 @@ CODE_SAMPLE
return true;
}
$classLike = $funcCall->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($funcCall, Class_::class);
if (! $classLike instanceof Class_) {
return true;
}

View File

@ -14,7 +14,6 @@ use PhpParser\NodeTraverser;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -99,7 +98,7 @@ CODE_SAMPLE
private function isPropertyInitiatedInConstuctor(Property $property, string $propertyName): bool
{
$classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($property, Class_::class);
if (! $classLike instanceof Class_) {
return false;
}

View File

@ -8,12 +8,13 @@ use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\Trait_;
use PhpParser\Node\UnionType as PhpParserUnionType;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\Generic\TemplateType;
use PHPStan\Type\MixedType;
use PHPStan\Type\NullType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\NodeAnalyzer\PropertyAnalyzer;
@ -23,6 +24,7 @@ use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\DeadCode\PhpDoc\TagRemover\VarTagRemover;
use Rector\FamilyTree\Reflection\FamilyRelationsAnalyzer;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Php74\TypeAnalyzer\PropertyUnionTypeResolver;
use Rector\PHPStanStaticTypeMapper\DoctrineTypeAnalyzer;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
@ -73,7 +75,8 @@ final class TypedPropertyRector extends AbstractRector implements ConfigurableRe
private ReflectionProvider $reflectionProvider,
private PropertyFetchAnalyzer $propertyFetchAnalyzer,
private FamilyRelationsAnalyzer $familyRelationsAnalyzer,
private PropertyAnalyzer $propertyAnalyzer
private PropertyAnalyzer $propertyAnalyzer,
private PropertyUnionTypeResolver $propertyUnionTypeResolver
) {
}
@ -199,7 +202,8 @@ CODE_SAMPLE
return true;
}
$type = $this->resolveTypePossibleUnionNullableType($node, $type);
$type = $this->propertyUnionTypeResolver->resolve($node, $type);
// is not class-type and should be skipped
if ($this->shouldSkipNonClassLikeType($node, $type)) {
return true;
@ -217,28 +221,6 @@ CODE_SAMPLE
return true;
}
private function resolveTypePossibleUnionNullableType(
Name|NullableType|\PhpParser\Node\UnionType $node,
Type $possibleUnionType
): Type {
if (! $node instanceof NullableType) {
return $possibleUnionType;
}
if (! $possibleUnionType instanceof UnionType) {
return $possibleUnionType;
}
$types = $possibleUnionType->getTypes();
foreach ($types as $type) {
if (! $type instanceof NullType) {
return $type;
}
}
return $possibleUnionType;
}
private function shouldSkipNonClassLikeType(Name|NullableType|PhpParserUnionType $node, Type $type): bool
{
// unwrap nullable type
@ -278,7 +260,7 @@ CODE_SAMPLE
return;
}
if (! $propertyType->isSuperTypeOf(new NullType())->yes()) {
if (! TypeCombinator::containsNull($propertyType)) {
return;
}
@ -308,6 +290,12 @@ CODE_SAMPLE
return true;
}
$trait = $this->betterNodeFinder->findParentType($property, Trait_::class);
// skip trait properties, as they ar unpredictable based on class context they appear in
if ($trait instanceof Trait_) {
return true;
}
if (! $this->privatePropertyOnly) {
return $this->propertyAnalyzer->hasForbiddenType($property);
}

View File

@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Rector\Php74\TypeAnalyzer;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PHPStan\Type\NullType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
final class PropertyUnionTypeResolver
{
public function resolve(Name|NullableType|\PhpParser\Node\UnionType $phpUnionType, Type $possibleUnionType): Type
{
if (! $phpUnionType instanceof NullableType) {
return $possibleUnionType;
}
if (! $possibleUnionType instanceof UnionType) {
return $possibleUnionType;
}
$types = $possibleUnionType->getTypes();
foreach ($types as $type) {
if (! $type instanceof NullType) {
return $type;
}
}
return $possibleUnionType;
}
}

View File

@ -109,7 +109,6 @@ final class PhpSpecRenaming
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
$newClassName = StaticRectorStrings::removePrefixes($className, ['spec\\']);
return StaticRectorStrings::removeSuffixes($newClassName, [self::SPEC]);
}

View File

@ -8,7 +8,6 @@ use PhpParser\Node;
use PhpParser\Node\Stmt\ClassLike;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -61,13 +60,17 @@ CODE_SAMPLE
]);
}
public function isInPhpSpecBehavior(Node $node): bool
protected function isInPhpSpecBehavior(Node $node): bool
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
if ($node instanceof ClassLike) {
return $this->isObjectType($node, new ObjectType('PhpSpec\ObjectBehavior'));
}
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return false;
}
return $this->isObjectType($classLike, new ObjectType('PhpSpec\ObjectBehavior'));
return $this->isInPhpSpecBehavior($classLike);
}
}

View File

@ -63,7 +63,6 @@ final class PhpSpecMocksToPHPUnitMocksRector extends AbstractPhpSpecToPHPUnitRec
}
$this->processMethodParamsToMocks($node);
return $node;
}
@ -93,35 +92,35 @@ final class PhpSpecMocksToPHPUnitMocksRector extends AbstractPhpSpecToPHPUnitRec
private function processMethodCall(MethodCall $methodCall): ?MethodCall
{
if ($this->isName($methodCall->name, 'shouldBeCalled')) {
if (! $methodCall->var instanceof MethodCall) {
throw new ShouldNotHappenException();
}
$mockMethodName = $this->getName($methodCall->var->name);
if ($mockMethodName === null) {
throw new ShouldNotHappenException();
}
$arg = $methodCall->var->args[0] ?? null;
$expectedArg = $arg instanceof Arg ? $arg->value : null;
$methodCall->var->name = new Identifier('expects');
$thisOnceMethodCall = $this->nodeFactory->createLocalMethodCall('atLeastOnce');
$methodCall->var->args = [new Arg($thisOnceMethodCall)];
$methodCall->name = new Identifier('method');
$methodCall->args = [new Arg(new String_($mockMethodName))];
if ($expectedArg !== null) {
return $this->appendWithMethodCall($methodCall, $expectedArg);
}
return $methodCall;
if (! $this->isName($methodCall->name, 'shouldBeCalled')) {
return null;
}
return null;
if (! $methodCall->var instanceof MethodCall) {
throw new ShouldNotHappenException();
}
$mockMethodName = $this->getName($methodCall->var->name);
if ($mockMethodName === null) {
throw new ShouldNotHappenException();
}
$arg = $methodCall->var->args[0] ?? null;
$expectedArg = $arg instanceof Arg ? $arg->value : null;
$methodCall->var->name = new Identifier('expects');
$thisOnceMethodCall = $this->nodeFactory->createLocalMethodCall('atLeastOnce');
$methodCall->var->args = [new Arg($thisOnceMethodCall)];
$methodCall->name = new Identifier('method');
$methodCall->args = [new Arg(new String_($mockMethodName))];
if ($expectedArg !== null) {
return $this->appendWithMethodCall($methodCall, $expectedArg);
}
return $methodCall;
}
/**
@ -130,7 +129,7 @@ final class PhpSpecMocksToPHPUnitMocksRector extends AbstractPhpSpecToPHPUnitRec
private function createCreateMockCall(Param $param, Name $name): ?Expression
{
/** @var Class_ $classLike */
$classLike = $param->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($param, Class_::class);
$classMocks = $this->phpSpecMockCollector->resolveClassMocksFromParam($classLike);

View File

@ -17,7 +17,6 @@ use PhpParser\Node\Identifier;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PhpSpecToPHPUnit\MatchersManipulator;
use Rector\PhpSpecToPHPUnit\Naming\PhpSpecRenaming;
use Rector\PhpSpecToPHPUnit\NodeFactory\AssertMethodCallFactory;
@ -175,13 +174,18 @@ final class PhpSpecPromisesToPHPUnitAssertRector extends AbstractPhpSpecToPHPUni
}
/** @var Class_ $classLike */
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
$classMethod = $classLike->getMethod($methodName);
// it's a method call, skip
if ($classMethod !== null) {
return null;
}
// direct PHPUnit method calls, no need to call on property
if (in_array($methodName, ['atLeastOnce', 'equalTo', 'isInstanceOf', 'isType'], true)) {
return $node;
}
$node->var = $this->getTestedObjectPropertyFetch();
return $node;
@ -202,12 +206,19 @@ final class PhpSpecPromisesToPHPUnitAssertRector extends AbstractPhpSpecToPHPUni
return;
}
/** @var Class_ $classLike */
$classLike = $methodCall->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($methodCall, Class_::class);
if (! $class instanceof Class_) {
return;
}
$this->matchersKeys = $this->matchersManipulator->resolveMatcherNamesFromClass($classLike);
$this->testedClass = $this->phpSpecRenaming->resolveTestedClass($methodCall);
$this->testedObjectPropertyFetch = $this->createTestedObjectPropertyFetch($classLike);
$className = $this->getName($class);
if (! is_string($className)) {
return;
}
$this->matchersKeys = $this->matchersManipulator->resolveMatcherNamesFromClass($class);
$this->testedClass = $this->phpSpecRenaming->resolveTestedClass($class);
$this->testedObjectPropertyFetch = $this->createTestedObjectPropertyFetch($class);
$this->isPrepared = true;
}
@ -284,7 +295,6 @@ final class PhpSpecPromisesToPHPUnitAssertRector extends AbstractPhpSpecToPHPUni
private function createTestedObjectPropertyFetch(Class_ $class): PropertyFetch
{
$propertyName = $this->phpSpecRenaming->resolveObjectPropertyName($class);
return new PropertyFetch(new Variable(self::THIS), $propertyName);
}
}

View File

@ -12,7 +12,6 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Global_;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\PropertyToAddCollector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -91,7 +90,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -12,7 +12,6 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Return_;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -86,7 +85,7 @@ CODE_SAMPLE
return null;
}
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -11,7 +11,6 @@ use PhpParser\Node\Stmt\PropertyProperty;
use PHPStan\Type\ObjectType;
use Rector\Core\NodeManipulator\PropertyManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Privatization\NodeFactory\ClassConstantFactory;
use Rector\Privatization\NodeReplacer\PropertyFetchWithConstFetchReplacer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@ -114,7 +113,7 @@ CODE_SAMPLE
}
/** @var Class_ $classLike */
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
$this->propertyFetchWithConstFetchReplacer->replace($classLike, $node);
return $this->classConstantFactory->createFromProperty($node);
@ -126,7 +125,7 @@ CODE_SAMPLE
return true;
}
$classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($property, Class_::class);
if (! $classLike instanceof Class_) {
return true;
}

View File

@ -53,7 +53,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -120,7 +120,7 @@ final class ComplexNodeRemover
return;
}
$class = $assign->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($assign, Class_::class);
if (! $class instanceof Class_) {
return;
}

View File

@ -116,13 +116,13 @@ CODE_SAMPLE
private function refactorStaticCall(StaticCall $staticCall): ?MethodCall
{
$class = $staticCall->getAttribute(AttributeKey::CLASS_NODE);
if (! $class instanceof ClassLike) {
$classLike = $this->betterNodeFinder->findParentType($staticCall, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return null;
}
/** @var ClassMethod[] $classMethods */
$classMethods = $this->betterNodeFinder->findInstanceOf($class, ClassMethod::class);
$classMethods = $this->betterNodeFinder->findInstanceOf($classLike, ClassMethod::class);
foreach ($classMethods as $classMethod) {
if (! $this->isClassMethodMatchingStaticCall($classMethod, $staticCall)) {

View File

@ -111,7 +111,7 @@ CODE_SAMPLE
$propertyName = $this->propertyNaming->fqnToVariableName($staticObjectType);
/** @var Class_ $class */
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
$propertyMetadata = new PropertyMetadata($propertyName, $staticObjectType, Class_::MODIFIER_PRIVATE);
$this->propertyToAddCollector->addPropertyToClass($class, $propertyMetadata);

View File

@ -10,7 +10,6 @@ use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockTagReplacer;
use Rector\Renaming\ValueObject\RenameAnnotation;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
@ -90,7 +89,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -15,7 +15,6 @@ use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\NodeManipulator\ClassManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Renaming\Collector\MethodCallRenameCollector;
use Rector\Renaming\Contract\MethodCallRenameInterface;
use Rector\Renaming\ValueObject\MethodCallRename;
@ -145,7 +144,7 @@ CODE_SAMPLE
ClassMethod $classMethod,
MethodCallRenameInterface $methodCallRename
): bool {
$classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($classMethod, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return false;
}

View File

@ -7,6 +7,7 @@ namespace Rector\Renaming\Rector\PropertyFetch;
use PhpParser\Node;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\VarLikeIdentifier;
@ -14,7 +15,6 @@ use PHPStan\Type\ObjectType;
use PHPStan\Type\ThisType;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Renaming\ValueObject\RenameProperty;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -120,7 +120,8 @@ final class RenamePropertyRector extends AbstractRector implements ConfigurableR
private function processFromPropertyFetch(PropertyFetch $propertyFetch): ?PropertyFetch
{
$class = $propertyFetch->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($propertyFetch, Class_::class);
foreach ($this->renamedProperties as $renamedProperty) {
if (! $this->isObjectType($propertyFetch->var, $renamedProperty->getObjectType())) {
continue;

View File

@ -15,7 +15,6 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PhpParser\Node\Stmt\PropertyProperty;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -114,7 +113,7 @@ CODE_SAMPLE
private function isPropertyNullChecked(PropertyProperty $onlyPropertyProperty): bool
{
$classLike = $onlyPropertyProperty->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($onlyPropertyProperty, Class_::class);
if (! $classLike instanceof Class_) {
return false;
}

View File

@ -14,7 +14,6 @@ use PHPStan\Type\MixedType;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Transform\ValueObject\SingleToManyMethod;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -88,7 +87,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return null;
}

View File

@ -122,7 +122,7 @@ CODE_SAMPLE
}
/** @var Class_ $classLike */
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
foreach ($this->argumentFuncCallToMethodCalls as $argumentFuncCallToMethodCall) {
if (! $this->isName($node, $argumentFuncCallToMethodCall->getFunction())) {

View File

@ -93,7 +93,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -14,7 +14,6 @@ use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\NodeAnalyzer\PropertyPresenceChecker;
use Rector\Core\Rector\AbstractRector;
use Rector\Naming\Naming\PropertyNaming;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\PropertyToAddCollector;
use Rector\PostRector\ValueObject\PropertyMetadata;
use Rector\Transform\ValueObject\MethodCallToMethodCall;
@ -112,7 +111,11 @@ CODE_SAMPLE
$propertyFetch = $node->var;
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $class instanceof Class_) {
continue;
}
$newObjectType = new ObjectType($methodCallToMethodCall->getNewType());
$newPropertyName = $this->matchNewPropertyName($methodCallToMethodCall, $class);

View File

@ -15,7 +15,6 @@ use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
use Rector\Core\Rector\AbstractRector;
use Rector\Naming\Naming\PropertyNaming;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\PropertyToAddCollector;
use Rector\PostRector\ValueObject\PropertyMetadata;
use Rector\Transform\ValueObject\ServiceGetterToConstructorInjection;
@ -137,7 +136,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -16,7 +16,6 @@ use Rector\Core\Rector\AbstractRector;
use Rector\Naming\Naming\PropertyNaming;
use Rector\Naming\ValueObject\ExpectedName;
use Rector\NodeRemoval\AssignRemover;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PostRector\Collector\PropertyToAddCollector;
use Rector\PostRector\ValueObject\PropertyMetadata;
use Rector\Transform\NodeFactory\PropertyFetchFactory;
@ -171,7 +170,7 @@ CODE_SAMPLE
continue;
}
$classLike = $new->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($new, Class_::class);
if (! $classLike instanceof Class_) {
continue;
}

View File

@ -102,7 +102,7 @@ CODE_SAMPLE
}
/** @var Class_ $class */
$class = $node->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($node, Class_::class);
$propertyName = $this->getExistingFactoryPropertyName(
$class,

View File

@ -107,7 +107,7 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
if (! $classLike instanceof Class_) {
return null;
}

View File

@ -15,7 +15,6 @@ use PHPStan\Type\MixedType;
use PHPStan\Type\StringType;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\TypeComparator\TypeComparator;
use Rector\PHPStanStaticTypeMapper\Enum\TypeKind;
use Rector\TypeDeclaration\ValueObject\AddParamTypeDeclaration;
@ -92,7 +91,7 @@ CODE_SAMPLE
}
/** @var ClassLike $classLike */
$classLike = $node->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($node, Class_::class);
foreach ($this->parameterTypehints as $parameterTypehint) {
if (! $this->isObjectType($classLike, $parameterTypehint->getObjectType())) {
@ -127,7 +126,7 @@ CODE_SAMPLE
return true;
}
$classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($classMethod, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return true;
}

View File

@ -230,7 +230,7 @@ CODE_SAMPLE
return false;
}
$classLike = $functionLike->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($functionLike, Class_::class);
return ! $classLike instanceof Class_;
}
}

View File

@ -15,6 +15,7 @@ use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer;
use Rector\Core\NodeManipulator\PropertyFetchAssignManipulator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\TypeDeclaration\Contract\TypeInferer\ParamTypeInfererInterface;
@ -27,14 +28,15 @@ final class GetterNodeParamTypeInferer implements ParamTypeInfererInterface
private PropertyFetchAnalyzer $propertyFetchAnalyzer,
private PhpDocInfoFactory $phpDocInfoFactory,
private NodeNameResolver $nodeNameResolver,
private SimpleCallableNodeTraverser $simpleCallableNodeTraverser
private SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
private BetterNodeFinder $betterNodeFinder,
) {
}
public function inferParam(Param $param): Type
{
$classLike = $param->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($param, Class_::class);
if (! $class instanceof Class_) {
return new MixedType();
}
@ -55,7 +57,7 @@ final class GetterNodeParamTypeInferer implements ParamTypeInfererInterface
$returnType = new MixedType();
// resolve property assigns
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($classLike, function (Node $node) use (
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($class, function (Node $node) use (
$propertyNames,
&$returnType
): ?int {

View File

@ -11,26 +11,27 @@ use PHPStan\Type\ArrayType;
use PHPStan\Type\MixedType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\TypeDeclaration\Contract\TypeInferer\ParamTypeInfererInterface;
final class KnownArrayParamTypeInferer implements ParamTypeInfererInterface
{
public function __construct(
private NodeNameResolver $nodeNameResolver,
private ReflectionProvider $reflectionProvider
private ReflectionProvider $reflectionProvider,
private BetterNodeFinder $betterNodeFinder,
) {
}
public function inferParam(Param $param): Type
{
$classLike = $param->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($param, Class_::class);
if (! $class instanceof Class_) {
return new MixedType();
}
$className = $this->nodeNameResolver->getName($classLike);
$className = $this->nodeNameResolver->getName($class);
if (! $className) {
return new MixedType();
}

View File

@ -85,8 +85,8 @@ final class PHPUnitDataProviderParamTypeInferer implements ParamTypeInfererInter
return null;
}
$classLike = $param->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($param, Class_::class);
if (! $class instanceof Class_) {
return null;
}
@ -101,7 +101,7 @@ final class PHPUnitDataProviderParamTypeInferer implements ParamTypeInfererInter
}
$methodName = $match['method_name'];
return $classLike->getMethod($methodName);
return $class->getMethod($methodName);
}
/**

View File

@ -12,6 +12,7 @@ use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\Core\NodeAnalyzer\PropertyFetchAnalyzer;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@ -26,13 +27,14 @@ final class PropertyNodeParamTypeInferer implements ParamTypeInfererInterface
private NodeNameResolver $nodeNameResolver,
private SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
private NodeTypeResolver $nodeTypeResolver,
private TypeFactory $typeFactory
private TypeFactory $typeFactory,
private BetterNodeFinder $betterNodeFinder
) {
}
public function inferParam(Param $param): Type
{
$classLike = $param->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($param, Class_::class);
if (! $classLike instanceof Class_) {
return new MixedType();
}

View File

@ -4,10 +4,11 @@ declare(strict_types=1);
namespace Rector\TypeDeclaration\TypeInferer\PropertyTypeInferer;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Property;
use PHPStan\Type\Type;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\TypeDeclaration\Contract\TypeInferer\PropertyTypeInfererInterface;
use Rector\TypeDeclaration\TypeInferer\AssignToPropertyTypeInferer;
@ -15,21 +16,21 @@ final class AllAssignNodePropertyTypeInferer implements PropertyTypeInfererInter
{
public function __construct(
private AssignToPropertyTypeInferer $assignToPropertyTypeInferer,
private NodeNameResolver $nodeNameResolver
private NodeNameResolver $nodeNameResolver,
private BetterNodeFinder $betterNodeFinder
) {
}
public function inferProperty(Property $property): ?Type
{
$classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
if ($classLike === null) {
// anonymous class possibly?
$class = $this->betterNodeFinder->findParentType($property, Class_::class);
if (! $class instanceof Class_) {
return null;
}
$propertyName = $this->nodeNameResolver->getName($property);
return $this->assignToPropertyTypeInferer->inferPropertyInClassLike($propertyName, $classLike);
return $this->assignToPropertyTypeInferer->inferPropertyInClassLike($propertyName, $class);
}
public function getPriority(): int

View File

@ -9,8 +9,8 @@ use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\TypeDeclaration\Contract\TypeInferer\PropertyTypeInfererInterface;
use Rector\TypeDeclaration\FunctionLikeReturnTypeResolver;
use Rector\TypeDeclaration\NodeAnalyzer\ClassMethodAndPropertyAnalyzer;
@ -24,14 +24,15 @@ final class GetterPropertyTypeInferer implements PropertyTypeInfererInterface
private ReturnedNodesReturnTypeInferer $returnedNodesReturnTypeInferer,
private FunctionLikeReturnTypeResolver $functionLikeReturnTypeResolver,
private ClassMethodAndPropertyAnalyzer $classMethodAndPropertyAnalyzer,
private NodeNameResolver $nodeNameResolver
private NodeNameResolver $nodeNameResolver,
private BetterNodeFinder $betterNodeFinder,
) {
}
public function inferProperty(Property $property): ?Type
{
$classLike = $property->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($property, Class_::class);
if (! $class instanceof Class_) {
// anonymous class
return null;
}
@ -39,7 +40,7 @@ final class GetterPropertyTypeInferer implements PropertyTypeInfererInterface
/** @var string $propertyName */
$propertyName = $this->nodeNameResolver->getName($property);
foreach ($classLike->getMethods() as $classMethod) {
foreach ($class->getMethods() as $classMethod) {
if (! $this->classMethodAndPropertyAnalyzer->hasClassMethodOnlyStatementReturnOfPropertyFetch(
$classMethod,
$propertyName

View File

@ -9,6 +9,7 @@ use PhpParser\Node\Expr\Closure;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Interface_;
@ -21,9 +22,9 @@ use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use PHPStan\Type\VoidType;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\TypeDeclaration\Contract\TypeInferer\ReturnTypeInfererInterface;
@ -41,7 +42,8 @@ final class ReturnedNodesReturnTypeInferer implements ReturnTypeInfererInterface
private SplArrayFixedTypeNarrower $splArrayFixedTypeNarrower,
private AstResolver $reflectionAstResolver,
private BetterStandardPrinter $betterStandardPrinter,
private ReflectionResolver $reflectionResolver
private ReflectionResolver $reflectionResolver,
private BetterNodeFinder $betterNodeFinder,
) {
}
@ -50,9 +52,8 @@ final class ReturnedNodesReturnTypeInferer implements ReturnTypeInfererInterface
*/
public function inferFunctionLike(FunctionLike $functionLike): Type
{
/** @var Class_|Trait_|Interface_|null $classLike */
$classLike = $functionLike->getAttribute(AttributeKey::CLASS_NODE);
if ($classLike === null) {
$classLike = $this->betterNodeFinder->findParentType($functionLike, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return new MixedType();
}
@ -64,6 +65,7 @@ final class ReturnedNodesReturnTypeInferer implements ReturnTypeInfererInterface
$localReturnNodes = $this->collectReturns($functionLike);
if ($localReturnNodes === []) {
/** @var Class_|Interface_|Trait_ $classLike */
return $this->resolveNoLocalReturnNodes($classLike, $functionLike);
}

View File

@ -9,7 +9,7 @@ use PhpParser\Node\Stmt\ClassLike;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\Core\NodeManipulator\FunctionLikeManipulator;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
use Rector\TypeDeclaration\Contract\TypeInferer\ReturnTypeInfererInterface;
use Rector\TypeDeclaration\TypeInferer\AssignToPropertyTypeInferer;
@ -19,13 +19,14 @@ final class SetterNodeReturnTypeInferer implements ReturnTypeInfererInterface
public function __construct(
private AssignToPropertyTypeInferer $assignToPropertyTypeInferer,
private FunctionLikeManipulator $functionLikeManipulator,
private TypeFactory $typeFactory
private TypeFactory $typeFactory,
private BetterNodeFinder $betterNodeFinder,
) {
}
public function inferFunctionLike(FunctionLike $functionLike): Type
{
$classLike = $functionLike->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($functionLike, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return new MixedType();
}

View File

@ -15,10 +15,8 @@ use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Return_;
use PhpParser\Node\Stmt\Switch_;
use PhpParser\Node\Stmt\Throw_;
use PhpParser\Node\Stmt\Trait_;
use PhpParser\Node\Stmt\TryCatch;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class SilentVoidResolver
{
@ -29,12 +27,8 @@ final class SilentVoidResolver
public function hasExclusiveVoid(ClassMethod | Closure | Function_ $functionLike): bool
{
$classLike = $functionLike->getAttribute(AttributeKey::CLASS_NODE);
if ($classLike instanceof Interface_) {
return false;
}
if ($classLike instanceof Trait_) {
$interface = $this->betterNodeFinder->findParentType($functionLike, Interface_::class);
if ($interface instanceof Interface_) {
return false;
}

View File

@ -6,13 +6,14 @@ namespace Rector\Core\NodeAnalyzer;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassConst;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class EnumAnalyzer
{
public function __construct(
private NodeNameResolver $nodeNameResolver
private NodeNameResolver $nodeNameResolver,
private BetterNodeFinder $betterNodeFinder,
) {
}
@ -21,15 +22,15 @@ final class EnumAnalyzer
*/
public function isEnumClassConst(ClassConst $classConst): bool
{
$classLike = $classConst->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($classConst, Class_::class);
if (! $class instanceof Class_) {
return false;
}
if ($classLike->extends === null) {
if ($class->extends === null) {
return false;
}
return $this->nodeNameResolver->isName($classLike->extends, '*Enum');
return $this->nodeNameResolver->isName($class->extends, '*Enum');
}
}

View File

@ -20,7 +20,6 @@ use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class PropertyFetchAnalyzer
{
@ -82,12 +81,12 @@ final class PropertyFetchAnalyzer
return false;
}
$classLike = $expr->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($expr, Class_::class);
if (! $class instanceof Class_) {
return false;
}
foreach ($classLike->getProperties() as $property) {
foreach ($class->getProperties() as $property) {
if (! $this->nodeNameResolver->areNamesEqual($property->props[0], $expr)) {
continue;
}
@ -130,7 +129,7 @@ final class PropertyFetchAnalyzer
public function isFilledByConstructParam(Property $property): bool
{
$class = $property->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($property, Class_::class);
if (! $class instanceof Class_) {
return false;
}

View File

@ -13,7 +13,6 @@ use PHPStan\Reflection\ClassReflection;
use Rector\Core\PhpParser\AstResolver;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ClassConstManipulator
{
@ -26,8 +25,8 @@ final class ClassConstManipulator
public function hasClassConstFetch(ClassConst $classConst, ClassReflection $classReflection): bool
{
$classLike = $classConst->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($classConst, Class_::class);
if (! $class instanceof Class_) {
return false;
}

View File

@ -64,8 +64,8 @@ final class ClassMethodManipulator
return false;
}
$classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
if (! $classLike instanceof Class_) {
$class = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
if (! $class instanceof Class_) {
return false;
}
@ -73,7 +73,7 @@ final class ClassMethodManipulator
return true;
}
if ($classLike->isFinal()) {
if ($class->isFinal()) {
return false;
}

View File

@ -76,8 +76,10 @@ final class PropertyManipulator
}
// has classLike $this->$variable call?
/** @var ClassLike $classLike */
$classLike = $propertyOrPromotedParam->getAttribute(AttributeKey::CLASS_NODE);
$classLike = $this->betterNodeFinder->findParentType($propertyOrPromotedParam, ClassLike::class);
if (! $classLike instanceof ClassLike) {
return false;
}
return (bool) $this->betterNodeFinder->findFirst($classLike->stmts, function (Node $node): bool {
if (! $node instanceof PropertyFetch) {

View File

@ -8,8 +8,8 @@ use PhpParser\Node\Const_;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Stmt\Class_;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
final class LocalConstantFinder
@ -17,12 +17,13 @@ final class LocalConstantFinder
public function __construct(
private NodeTypeResolver $nodeTypeResolver,
private NodeNameResolver $nodeNameResolver,
private BetterNodeFinder $betterNodeFinder,
) {
}
public function match(ClassConstFetch $classConstFetch): ?Const_
{
$class = $classConstFetch->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($classConstFetch, Class_::class);
if (! $class instanceof Class_) {
return null;
}

View File

@ -10,7 +10,6 @@ use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
final class LocalMethodCallFinder
@ -27,7 +26,7 @@ final class LocalMethodCallFinder
*/
public function match(ClassMethod $classMethod): array
{
$class = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
$class = $this->betterNodeFinder->findParentType($classMethod, Class_::class);
if (! $class instanceof Class_) {
return [];
}

View File

@ -62,7 +62,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
* @var string[]
*/
private const ATTRIBUTES_TO_MIRROR = [
AttributeKey::CLASS_NODE,
AttributeKey::CLASS_NAME,
AttributeKey::METHOD_NODE,
AttributeKey::USE_NODES,