[DX] remove isStaticCallNamed() (#5913)

Co-authored-by: kaizen-ci <info@kaizen-ci.org>
This commit is contained in:
Tomas Votruba 2021-03-20 01:06:12 +01:00 committed by GitHub
parent c01d9699b5
commit 9d101f6e30
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 201 additions and 124 deletions

View File

@ -8,7 +8,6 @@ use Nette\Utils\Strings;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
@ -213,61 +212,6 @@ final class NodeNameResolver
return (bool) Strings::match($currentName, $suffixNamePattern);
}
public function isLocalMethodCallNamed(Node $node, string $name): bool
{
if (! $node instanceof MethodCall) {
return false;
}
if ($node->var instanceof StaticCall) {
return false;
}
if ($node->var instanceof MethodCall) {
return false;
}
if (! $this->isName($node->var, 'this')) {
return false;
}
return $this->isName($node->name, $name);
}
/**
* @param string[] $names
*/
public function isLocalMethodCallsNamed(Node $node, array $names): bool
{
foreach ($names as $name) {
if ($this->isLocalMethodCallNamed($node, $name)) {
return true;
}
}
return false;
}
/**
* @deprecated Helper function causes to lose the type on the outside. Better avoid it
*/
public function isStaticCallNamed(Node $node, string $className, string $methodName): bool
{
if (! $node instanceof StaticCall) {
return false;
}
if ($node->class instanceof New_) {
if (! $this->isName($node->class->class, $className)) {
return false;
}
} elseif (! $this->isName($node->class, $className)) {
return false;
}
return $this->isName($node->name, $methodName);
}
/**
* @param ObjectType[] $desiredObjectTypes
*/

View File

@ -9,6 +9,7 @@ use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt\Declare_;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\Node\Stmt\Use_;
use PHPStan\Type\ObjectType;
use Rector\CakePHP\Naming\CakePHPFullyQualifiedClassNameResolver;
use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
use Rector\Core\Rector\AbstractRector;
@ -94,7 +95,12 @@ CODE_SAMPLE
return false;
}
return $this->nodeNameResolver->isStaticCallNamed($node, 'App', 'uses');
$callerType = $this->nodeTypeResolver->resolve($node->class);
if (! $callerType->isSuperTypeOf(new ObjectType('App'))->yes()) {
return false;
}
return $this->isName($node->name, 'uses');
});
return $appUsesStaticCalls;

View File

@ -167,6 +167,7 @@ CODE_SAMPLE
return false;
}
return $scope->hasVariableType($variableName)->yes();
return $scope->hasVariableType($variableName)
->yes();
}
}

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Rector\DependencyInjection\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
@ -139,7 +140,15 @@ CODE_SAMPLE
return (bool) $this->betterNodeFinder->findFirst((array) $classMethod->stmts, function (Node $node) use (
$method
): bool {
return $this->nodeNameResolver->isStaticCallNamed($node, 'parent', $method);
if (! $node instanceof StaticCall) {
return false;
}
if (! $this->isName($node->class, 'parent')) {
return false;
}
return $this->isName($node->name, $method);
});
}
}

View File

@ -10,6 +10,7 @@ use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\ClassMethod;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\MockeryToProphecy\Collector\MockVariableCollector;
use Rector\NodeTypeResolver\Node\AttributeKey;
@ -96,12 +97,21 @@ CODE_SAMPLE
}
$this->traverseNodesWithCallable($classMethod->stmts, function (Node $node): ?MethodCall {
if (! $this->nodeNameResolver->isStaticCallNamed($node, 'Mockery', 'mock')) {
if (! $node instanceof StaticCall) {
return null;
}
$callerType = $this->nodeTypeResolver->resolve($node->class);
if (! $callerType->isSuperTypeOf(new ObjectType('Mockery'))->yes()) {
return null;
}
if (! $this->isName($node->name, 'mock')) {
return null;
}
/** @var StaticCall $node */
$collectedVariableTypesByNames = $this->mockVariableCollector->collectMockVariableName($node);
$this->mockVariableTypesByNames = array_merge(
$this->mockVariableTypesByNames,
$collectedVariableTypesByNames

View File

@ -6,6 +6,7 @@ namespace Rector\MockeryToProphecy\Rector\StaticCall;
use PhpParser\Node;
use PhpParser\Node\Expr\StaticCall;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Rector\PHPUnit\NodeAnalyzer\TestsNodeAnalyzer;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@ -43,7 +44,12 @@ final class MockeryCloseRemoveRector extends AbstractRector
return null;
}
if (! $this->nodeNameResolver->isStaticCallNamed($node, 'Mockery', 'close')) {
$callerType = $this->nodeTypeResolver->resolve($node->class);
if (! $callerType->isSuperTypeOf(new ObjectType('Mockery'))->yes()) {
return null;
}
if (! $this->isName($node->name, 'close')) {
return null;
}

View File

@ -7,6 +7,7 @@ namespace Rector\PHPOffice\Rector\StaticCall;
use PhpParser\Node;
use PhpParser\Node\Arg;
use PhpParser\Node\Expr\StaticCall;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -58,7 +59,12 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
if (! $this->nodeNameResolver->isStaticCallNamed($node, 'PHPExcel_Settings', 'setChartRenderer')) {
$callerType = $this->nodeTypeResolver->resolve($node->class);
if (! $callerType->isSuperTypeOf(new ObjectType('PHPExcel_Settings'))->yes()) {
return null;
}
if (! $this->nodeNameResolver->isName($node->name, 'setChartRenderer')) {
return null;
}

View File

@ -7,6 +7,7 @@ namespace Rector\PHPOffice\Rector\StaticCall;
use PhpParser\Node;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name\FullyQualified;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -60,7 +61,12 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
if (! $this->nodeNameResolver->isStaticCallNamed($node, 'PHPExcel_Cell_DataType', 'dataTypeForValue')) {
$callerType = $this->nodeTypeResolver->resolve($node->class);
if (! $callerType->isSuperTypeOf(new ObjectType('PHPExcel_Cell_DataType'))->yes()) {
return null;
}
if (! $this->nodeNameResolver->isName($node->name, 'dataTypeForValue')) {
return null;
}

View File

@ -9,6 +9,8 @@ use PhpParser\Node;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name\FullyQualified;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -62,17 +64,17 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
if ($this->nodeNameResolver->isStaticCallNamed($node, 'PHPExcel_Settings', 'setPdfRendererName')) {
$callerType = $this->nodeTypeResolver->resolve($node->class);
if ($this->isSettingsPdfRendererStaticCall($callerType, $node)) {
$this->removeNode($node);
return null;
}
if ($this->nodeNameResolver->isStaticCallNamed($node, 'PHPExcel_Settings', 'setPdfRenderer')) {
$this->removeNode($node);
return null;
}
if ($this->nodeNameResolver->isStaticCallNamed($node, 'PHPExcel_IOFactory', 'createWriter')) {
if ($callerType->isSuperTypeOf(new ObjectType('PHPExcel_IOFactory'))->yes() && $this->nodeNameResolver->isName(
$node->name,
'createWriter'
)) {
if (! isset($node->args[1])) {
return null;
}
@ -85,4 +87,13 @@ CODE_SAMPLE
return $node;
}
private function isSettingsPdfRendererStaticCall(Type $callerType, StaticCall $staticCall): bool
{
if (! $callerType->isSuperTypeOf(new ObjectType('PHPExcel_Settings'))->yes()) {
return false;
}
return $this->nodeNameResolver->isNames($staticCall->name, ['setPdfRendererName', 'setPdfRenderer']);
}
}

View File

@ -8,6 +8,7 @@ use PhpParser\Node;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name\FullyQualified;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -61,7 +62,12 @@ CODE_SAMPLE
*/
public function refactor(Node $node): ?Node
{
if (! $this->nodeNameResolver->isStaticCallNamed($node, 'PHPExcel_IOFactory', 'addSearchLocation')) {
$callerType = $this->nodeTypeResolver->resolve($node->class);
if (! $callerType->isSuperTypeOf(new ObjectType('PHPExcel_IOFactory'))->yes()) {
return null;
}
if (! $this->isName($node->name, 'addSearchLocation')) {
return null;
}

View File

@ -5,6 +5,8 @@ declare(strict_types=1);
namespace Rector\Php70\Rector\ClassMethod;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
@ -97,7 +99,7 @@ CODE_SAMPLE
/** @var Expression $stmt */
$stmt = $node->stmts[0];
if ($this->nodeNameResolver->isLocalMethodCallNamed($stmt->expr, MethodName::CONSTRUCT)) {
if ($this->isLocalMethodCallNamed($stmt->expr, MethodName::CONSTRUCT)) {
$this->removeNode($node);
return null;
@ -204,4 +206,25 @@ CODE_SAMPLE
return $parentClassReflection->getName();
}
private function isLocalMethodCallNamed(Expr $expr, string $name): bool
{
if (! $expr instanceof MethodCall) {
return false;
}
if ($expr->var instanceof StaticCall) {
return false;
}
if ($expr->var instanceof MethodCall) {
return false;
}
if (! $this->isName($expr->var, 'this')) {
return false;
}
return $this->isName($expr->name, $name);
}
}

View File

@ -10,6 +10,7 @@ use PhpParser\Node\Expr\Cast\String_;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name;
use PHPStan\Type\ObjectType;
use Rector\Core\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -57,7 +58,12 @@ CODE_SAMPLE
return null;
}
if (! $this->nodeNameResolver->isStaticCallNamed($node, 'ReflectionFunction', 'export')) {
$callerType = $this->nodeTypeResolver->resolve($node->class);
if (! $callerType->isSuperTypeOf(new ObjectType('ReflectionFunction'))->yes()) {
return null;
}
if (! $this->isName($node->name, 'export')) {
return null;
}

View File

@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace Rector\RemovingStatic\NodeAnalyzer;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\ValueObject\MethodName;
use Rector\NodeNameResolver\NodeNameResolver;
final class SetUpClassMethodUpdater
{
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
public function __construct(NodeNameResolver $nodeNameResolver)
{
$this->nodeNameResolver = $nodeNameResolver;
}
public function updateSetUpMethod(
ClassMethod $setupClassMethod,
Expression $parentSetupStaticCall,
Expression $assign
): void {
$parentSetUpStaticCallPosition = $this->getParentSetUpStaticCallPosition($setupClassMethod);
if ($parentSetUpStaticCallPosition === null) {
$setupClassMethod->stmts = array_merge([$parentSetupStaticCall, $assign], (array) $setupClassMethod->stmts);
} else {
assert($setupClassMethod->stmts !== null);
array_splice($setupClassMethod->stmts, $parentSetUpStaticCallPosition + 1, 0, [$assign]);
}
}
private function getParentSetUpStaticCallPosition(ClassMethod $setupClassMethod): ?int
{
foreach ((array) $setupClassMethod->stmts as $position => $methodStmt) {
if ($methodStmt instanceof Expression) {
$methodStmt = $methodStmt->expr;
}
if (! $methodStmt instanceof StaticCall) {
continue;
}
if (! $methodStmt->class instanceof Name) {
continue;
}
if (! $this->nodeNameResolver->isName($methodStmt->class, 'parent')) {
continue;
}
if (! $this->nodeNameResolver->isName($methodStmt->name, MethodName::SET_UP)) {
continue;
}
return $position;
}
return null;
}
}

View File

@ -12,7 +12,6 @@ use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Property;
use PHPStan\Type\ObjectType;
@ -23,6 +22,7 @@ use Rector\Core\ValueObject\MethodName;
use Rector\Naming\Naming\PropertyNaming;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PHPUnit\NodeFactory\SetUpClassMethodFactory;
use Rector\RemovingStatic\NodeAnalyzer\SetUpClassMethodUpdater;
use Rector\RemovingStatic\NodeFactory\SelfContainerFactory;
use Rector\RemovingStatic\NodeFactory\SetUpFactory;
use Rector\RemovingStatic\ValueObject\PHPUnitClass;
@ -75,18 +75,25 @@ final class PHPUnitStaticToKernelTestCaseGetRector extends AbstractRector implem
*/
private $selfContainerFactory;
/**
* @var SetUpClassMethodUpdater
*/
private $setUpClassMethodUpdater;
public function __construct(
PropertyNaming $propertyNaming,
ClassInsertManipulator $classInsertManipulator,
SetUpClassMethodFactory $setUpClassMethodFactory,
SetUpFactory $setUpFactory,
SelfContainerFactory $selfContainerFactory
SelfContainerFactory $selfContainerFactory,
SetUpClassMethodUpdater $setUpClassMethodUpdater
) {
$this->propertyNaming = $propertyNaming;
$this->classInsertManipulator = $classInsertManipulator;
$this->setUpClassMethodFactory = $setUpClassMethodFactory;
$this->setUpFactory = $setUpFactory;
$this->selfContainerFactory = $selfContainerFactory;
$this->setUpClassMethodUpdater = $setUpClassMethodUpdater;
}
public function getRuleDefinition(): RuleDefinition
@ -234,7 +241,11 @@ CODE_SAMPLE
// get setup or create a setup add add it there
if ($setupClassMethod !== null) {
$this->updateSetUpMethod($setupClassMethod, $parentSetUpStaticCallExpression, $assign);
$this->setUpClassMethodUpdater->updateSetUpMethod(
$setupClassMethod,
$parentSetUpStaticCallExpression,
$assign
);
} else {
$setUpMethod = $this->setUpClassMethodFactory->createSetUpMethod([$assign]);
$this->classInsertManipulator->addAsFirstMethod($class, $setUpMethod);
@ -289,13 +300,14 @@ CODE_SAMPLE
}
/**
* @param ObjectType[] $newProperties
* @param ObjectType[] $propertyTypes
*/
private function addNewPropertiesToClass(Class_ $class, array $newProperties): Class_
private function addNewPropertiesToClass(Class_ $class, array $propertyTypes): Class_
{
$properties = [];
foreach ($newProperties as $newProperty) {
$properties[] = $this->createPropertyFromType($newProperty);
foreach ($propertyTypes as $propertyType) {
$propertyName = $this->propertyNaming->fqnToVariableName($propertyType);
$properties[] = $this->nodeFactory->createPrivatePropertyFromNameAndType($propertyName, $propertyType);
}
// add property to the start of the class
@ -315,42 +327,4 @@ CODE_SAMPLE
return new Expression($assign);
}
private function updateSetUpMethod(
ClassMethod $setupClassMethod,
Expression $parentSetupStaticCall,
Expression $assign
): void {
$parentSetUpStaticCallPosition = $this->getParentSetUpStaticCallPosition($setupClassMethod);
if ($parentSetUpStaticCallPosition === null) {
$setupClassMethod->stmts = array_merge([$parentSetupStaticCall, $assign], (array) $setupClassMethod->stmts);
} else {
assert($setupClassMethod->stmts !== null);
array_splice($setupClassMethod->stmts, $parentSetUpStaticCallPosition + 1, 0, [$assign]);
}
}
private function createPropertyFromType(ObjectType $objectType): Property
{
$propertyName = $this->propertyNaming->fqnToVariableName($objectType);
return $this->nodeFactory->createPrivatePropertyFromNameAndType($propertyName, $objectType);
}
private function getParentSetUpStaticCallPosition(ClassMethod $setupClassMethod): ?int
{
foreach ((array) $setupClassMethod->stmts as $position => $methodStmt) {
if ($methodStmt instanceof Expression) {
$methodStmt = $methodStmt->expr;
}
if (! $this->nodeNameResolver->isStaticCallNamed($methodStmt, 'parent', MethodName::SET_UP)) {
continue;
}
return $position;
}
return null;
}
}

View File

@ -62,11 +62,12 @@ CODE_SAMPLE
return null;
}
if (! $this->nodeNameResolver->isStaticCallNamed(
$node,
'Doctrine\Common\Annotations\AnnotationRegistry',
'registerFile'
)) {
$callerType = $this->nodeTypeResolver->resolve($node->class);
if (! $callerType->isSuperTypeOf(new ObjectType('Doctrine\Common\Annotations\AnnotationRegistry'))->yes()) {
return null;
}
if (! $this->isName($node->name, 'registerFile')) {
return null;
}