[DX] Move from CLASS_METHOD node attribute to parent finder (#1167)

This commit is contained in:
Tomas Votruba 2021-11-06 15:07:22 +01:00 committed by GitHub
parent c3b6efea7e
commit 824df97e93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 66 additions and 62 deletions

View File

@ -48,7 +48,6 @@ expectedArguments(
0,
\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE,
\Rector\NodeTypeResolver\Node\AttributeKey::CLASS_NAME,
\Rector\NodeTypeResolver\Node\AttributeKey::METHOD_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::NEXT_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_NODE,
@ -73,7 +72,6 @@ expectedArguments(
0,
\Rector\NodeTypeResolver\Node\AttributeKey::SCOPE,
\Rector\NodeTypeResolver\Node\AttributeKey::CLASS_NAME,
\Rector\NodeTypeResolver\Node\AttributeKey::METHOD_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::PARENT_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::NEXT_NODE,
\Rector\NodeTypeResolver\Node\AttributeKey::PREVIOUS_NODE,

View File

@ -40,7 +40,7 @@ final class AttributeKey
/**
* @deprecated Use
* @see BetterNodeFinder to find your parent nodes.
* @see BetterNodeFinder::findParentType($node, ClassLike::class) to find your parent nodes.
*
* @var string
*/
@ -52,6 +52,9 @@ final class AttributeKey
public const METHOD_NAME = 'methodName';
/**
* @deprecated Use
* @see BetterNodeFinder::findParentType($node, ClassMethod::class) to find your parent nodes.
*
* @var string
*/
public const METHOD_NODE = 'methodNode';

View File

@ -16,6 +16,7 @@ use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -36,7 +37,8 @@ final class ParamTypeResolver implements NodeTypeResolverInterface
public function __construct(
private SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
private NodeNameResolver $nodeNameResolver,
private PhpDocInfoFactory $phpDocInfoFactory
private PhpDocInfoFactory $phpDocInfoFactory,
private BetterNodeFinder $betterNodeFinder,
) {
}
@ -90,7 +92,7 @@ final class ParamTypeResolver implements NodeTypeResolverInterface
private function resolveFromFirstVariableUse(Param $param): Type
{
$classMethod = $param->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($param, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return new MixedType();
}

View File

@ -20,11 +20,6 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
*/
final class VariableTypeResolver implements NodeTypeResolverInterface
{
/**
* @var string[]
*/
private const PARENT_NODE_ATTRIBUTES = [AttributeKey::PARENT_NODE, AttributeKey::METHOD_NODE];
public function __construct(
private NodeNameResolver $nodeNameResolver,
private PhpDocInfoFactory $phpDocInfoFactory
@ -76,10 +71,9 @@ final class VariableTypeResolver implements NodeTypeResolverInterface
private function resolveNodeScope(Variable $variable): ?Scope
{
/** @var Scope|null $nodeScope */
$nodeScope = $variable->getAttribute(AttributeKey::SCOPE);
if ($nodeScope !== null) {
return $nodeScope;
$scope = $variable->getAttribute(AttributeKey::SCOPE);
if ($scope instanceof Scope) {
return $scope;
}
return $this->resolveFromParentNodes($variable);
@ -87,20 +81,11 @@ final class VariableTypeResolver implements NodeTypeResolverInterface
private function resolveFromParentNodes(Variable $variable): ?Scope
{
foreach (self::PARENT_NODE_ATTRIBUTES as $parentNodeAttribute) {
$parentNode = $variable->getAttribute($parentNodeAttribute);
if (! $parentNode instanceof Node) {
continue;
}
$parentNodeScope = $parentNode->getAttribute(AttributeKey::SCOPE);
if (! $parentNodeScope instanceof Scope) {
continue;
}
return $parentNodeScope;
$parent = $variable->getAttribute(AttributeKey::PARENT_NODE);
if (! $parent instanceof Node) {
return null;
}
return null;
return $parent->getAttribute(AttributeKey::SCOPE);
}
}

View File

@ -11,6 +11,7 @@ use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticPropertyFetch;
use PhpParser\Node\Expr\Ternary;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\Rector\AbstractRector;
use Rector\DeadCode\SideEffect\SideEffectNodeDetector;
@ -120,9 +121,12 @@ CODE_SAMPLE
private function areInSameClassMethod(Assign $assign, Expression $previousExpression): bool
{
return $this->nodeComparator->areNodesEqual(
$assign->getAttribute(AttributeKey::METHOD_NODE),
$previousExpression->getAttribute(AttributeKey::METHOD_NODE)
$assignClassMethod = $this->betterNodeFinder->findParentType($assign, ClassMethod::class);
$previousExpressionClassMethod = $this->betterNodeFinder->findParentType(
$previousExpression,
ClassMethod::class
);
return $this->nodeComparator->areNodesEqual($assignClassMethod, $previousExpressionClassMethod);
}
}

View File

@ -14,6 +14,7 @@ use PhpParser\Node\Expr\NullsafeMethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
use Rector\Core\Php\ReservedKeywordAnalyzer;
@ -114,7 +115,7 @@ CODE_SAMPLE
private function shouldSkip(Assign $assign): bool
{
$classMethod = $assign->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($assign, ClassMethod::class);
if (! $classMethod instanceof FunctionLike) {
return true;
}

View File

@ -95,7 +95,7 @@ CODE_SAMPLE
return null;
}
$classMethod = $node->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($node, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return null;
}

View File

@ -6,10 +6,16 @@ namespace Rector\DependencyInjection\NodeAnalyzer;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ControllerClassMethodAnalyzer
{
public function __construct(
private BetterNodeFinder $betterNodeFinder
) {
}
public function isInControllerActionMethod(Variable $variable): bool
{
/** @var string|null $className */
@ -22,7 +28,7 @@ final class ControllerClassMethodAnalyzer
return false;
}
$classMethod = $variable->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($variable, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return false;
}

View File

@ -14,6 +14,7 @@ use PhpParser\Node\Stmt\Property;
use PHPStan\Type\MixedType;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeManipulator\ClassInsertManipulator;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
@ -219,8 +220,12 @@ CODE_SAMPLE
private function decoratePropertyWithParamDocInfo(Param $param, Property $property): void
{
$constructor = $param->getAttribute(AttributeKey::METHOD_NODE);
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($constructor);
$constructorClassMethod = $this->betterNodeFinder->findParentType($param, ClassMethod::class);
if (! $constructorClassMethod instanceof ClassMethod) {
throw new ShouldNotHappenException();
}
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($constructorClassMethod);
if (! $phpDocInfo instanceof PhpDocInfo) {
return;
}

View File

@ -10,6 +10,7 @@ use PhpParser\Node\Param;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
@ -33,7 +34,8 @@ final class PhpSpecMockCollector
public function __construct(
private SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
private NodeNameResolver $nodeNameResolver
private NodeNameResolver $nodeNameResolver,
private BetterNodeFinder $betterNodeFinder,
) {
}
@ -101,7 +103,7 @@ final class PhpSpecMockCollector
/** @var string $class */
$class = $param->getAttribute(AttributeKey::CLASS_NAME);
$classMethod = $param->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($param, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
throw new ShouldNotHappenException();
}

View File

@ -135,7 +135,7 @@ final class PhpSpecMocksToPHPUnitMocksRector extends AbstractPhpSpecToPHPUnitRec
$variable = $this->getName($param->var);
$classMethod = $param->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($param, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
throw new ShouldNotHappenException();
}

View File

@ -103,7 +103,7 @@ CODE_SAMPLE
}
foreach ($readOnlyVariableAssigns as $readOnlyVariableAssign) {
$classMethod = $readOnlyVariableAssign->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($readOnlyVariableAssign, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
throw new ShouldNotHappenException();
}

View File

@ -85,7 +85,7 @@ final class ComplexNodeRemover
StaticPropertyFetch | PropertyFetch $expr,
array $classMethodNamesToSkip
): bool {
$classMethodNode = $expr->getAttribute(AttributeKey::METHOD_NODE);
$classMethodNode = $this->betterNodeFinder->findParentType($expr, ClassMethod::class);
if (! $classMethodNode instanceof ClassMethod) {
return false;
}
@ -111,7 +111,7 @@ final class ComplexNodeRemover
private function removeConstructorDependency(Assign $assign): void
{
$classMethod = $assign->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($assign, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return;
}

View File

@ -142,7 +142,7 @@ CODE_SAMPLE
private function isInStaticClassMethod(StaticCall $staticCall): bool
{
$locationClassMethod = $staticCall->getAttribute(AttributeKey::METHOD_NODE);
$locationClassMethod = $this->betterNodeFinder->findParentType($staticCall, ClassMethod::class);
if (! $locationClassMethod instanceof ClassMethod) {
return false;
}

View File

@ -9,12 +9,12 @@ use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\ObjectType;
use Rector\Core\Configuration\Option;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\ValueObject\MethodName;
use Rector\Naming\Naming\PropertyNaming;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\PackageBuilder\Parameter\ParameterProvider;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -92,7 +92,11 @@ CODE_SAMPLE
$propertyName = $this->propertyNaming->fqnToVariableName($staticObjectType);
$classMethod = $node->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($node, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return null;
}
if ($this->nodeNameResolver->isName($classMethod, MethodName::CONSTRUCT)) {
$propertyFetch = new Variable($propertyName);
} else {

View File

@ -16,7 +16,6 @@ use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\Naming\Naming\PropertyNaming;
use Rector\Naming\ValueObject\ExpectedName;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
use Rector\PostRector\Collector\PropertyToAddCollector;
use Rector\PostRector\ValueObject\PropertyMetadata;
@ -161,10 +160,9 @@ CODE_SAMPLE
private function shouldSkipFuncCall(FuncCall $funcCall): bool
{
// we can inject only in injectable class method context
// we can inject only in injectable class method context
/** @var ClassMethod|null $classMethod */
$classMethod = $funcCall->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($funcCall, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return true;
}

View File

@ -10,7 +10,6 @@ use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Transform\NodeAnalyzer\FuncCallStaticCallToMethodCallAnalyzer;
use Rector\Transform\ValueObject\FuncCallToMethodCall;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
@ -98,7 +97,7 @@ CODE_SAMPLE
return null;
}
$classMethod = $node->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($node, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return null;
}

View File

@ -14,7 +14,6 @@ use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\Transform\NodeAnalyzer\FuncCallStaticCallToMethodCallAnalyzer;
use Rector\Transform\ValueObject\StaticCallToMethodCall;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
@ -112,7 +111,7 @@ CODE_SAMPLE
return null;
}
$classMethod = $node->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($node, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return null;
}

View File

@ -75,7 +75,7 @@ final class GetterNodeParamTypeInferer implements ParamTypeInfererInterface
}
// what is return type?
$classMethod = $node->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($node, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return null;
}

View File

@ -117,13 +117,13 @@ final class ClassMethodManipulator
*/
public function addMethodParameterIfMissing(Node $node, ObjectType $objectType, array $possibleNames): string
{
$classMethodNode = $node->getAttribute(AttributeKey::METHOD_NODE);
if (! $classMethodNode instanceof ClassMethod) {
$classMethod = $this->betterNodeFinder->findParentType($node, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
// or null?
throw new ShouldNotHappenException();
}
foreach ($classMethodNode->params as $paramNode) {
foreach ($classMethod->params as $paramNode) {
if (! $this->nodeTypeResolver->isObjectType($paramNode, $objectType)) {
continue;
}
@ -136,8 +136,8 @@ final class ClassMethodManipulator
return $paramName;
}
$paramName = $this->resolveName($classMethodNode, $possibleNames);
$classMethodNode->params[] = new Param(new Variable($paramName), null, new FullyQualified(
$paramName = $this->resolveName($classMethod, $possibleNames);
$classMethod->params[] = new Param(new Variable($paramName), null, new FullyQualified(
$objectType->getClassName()
));

View File

@ -100,7 +100,7 @@ final class MethodCallManipulator
public function findMethodCallsOnVariable(Variable $variable): array
{
// get scope node, e.g. parent function call, method call or anonymous function
$classMethod = $variable->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($variable, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return [];
}

View File

@ -104,7 +104,7 @@ final class PropertyManipulator
}
// skip for constructor? it is allowed to set value in constructor method
$classMethod = $propertyFetch->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($propertyFetch, ClassMethod::class);
if ($classMethod instanceof ClassMethod && $this->nodeNameResolver->isName(
$classMethod->name,
MethodName::CONSTRUCT

View File

@ -21,7 +21,6 @@ use Rector\Core\PhpParser\Comparing\NodeComparator;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\Core\PhpParser\NodeFinder\LocalConstantFinder;
use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
final class RegexPatternArgumentManipulator
@ -163,7 +162,7 @@ final class RegexPatternArgumentManipulator
*/
private function findAssignerForVariable(Variable $variable): array
{
$classMethod = $variable->getAttribute(AttributeKey::METHOD_NODE);
$classMethod = $this->betterNodeFinder->findParentType($variable, ClassMethod::class);
if (! $classMethod instanceof ClassMethod) {
return [];
}

View File

@ -63,7 +63,6 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
*/
private const ATTRIBUTES_TO_MIRROR = [
AttributeKey::CLASS_NAME,
AttributeKey::METHOD_NODE,
AttributeKey::USE_NODES,
AttributeKey::SCOPE,
AttributeKey::RESOLVED_NAME,