diff --git a/composer.json b/composer.json
index 21ec6d145e0..e3d9be74332 100644
--- a/composer.json
+++ b/composer.json
@@ -58,6 +58,7 @@
"autoload": {
"psr-4": {
"Rector\\Architecture\\": "rules/architecture/src",
+ "Rector\\AnonymousClass\\": "packages/anonymous-class/src",
"Rector\\PostRector\\": "packages/post-rector/src",
"Rector\\AttributeAwarePhpDoc\\": "packages/attribute-aware-php-doc/src",
"Rector\\Autodiscovery\\": "rules/autodiscovery/src",
diff --git a/config/set/nette-application-code-quality.php b/config/set/nette-application-code-quality.php
index df6815a614c..35e8beeec01 100644
--- a/config/set/nette-application-code-quality.php
+++ b/config/set/nette-application-code-quality.php
@@ -2,6 +2,7 @@
declare(strict_types=1);
+use Rector\Nette\Rector\ArrayDimFetch\ChangeControlArrayAccessToAnnotatedControlVariableRector;
use Rector\Nette\Rector\Assign\MakeGetComponentAssignAnnotatedRector;
use Rector\Nette\Rector\ClassMethod\TemplateMagicAssignToExplicitVariableArrayRector;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
@@ -12,4 +13,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
$services->set(TemplateMagicAssignToExplicitVariableArrayRector::class);
$services->set(MakeGetComponentAssignAnnotatedRector::class);
+
+ $services->set(ChangeControlArrayAccessToAnnotatedControlVariableRector::class);
};
diff --git a/docs/rector_rules_overview.md b/docs/rector_rules_overview.md
index a72a57338bc..caf603e4cc3 100644
--- a/docs/rector_rules_overview.md
+++ b/docs/rector_rules_overview.md
@@ -1,4 +1,4 @@
-# All 534 Rectors Overview
+# All 536 Rectors Overview
- [Projects](#projects)
- [General](#general)
@@ -31,7 +31,7 @@
- [MockistaToMockery](#mockistatomockery) (2)
- [MysqlToMysqli](#mysqltomysqli) (4)
- [Naming](#naming) (3)
-- [Nette](#nette) (14)
+- [Nette](#nette) (15)
- [NetteCodeQuality](#nettecodequality) (1)
- [NetteKdyby](#nettekdyby) (4)
- [NetteTesterToPHPUnit](#nettetestertophpunit) (3)
@@ -5184,6 +5184,37 @@ Nextras/Form upgrade of addDatePicker method call to DateControl assign
+### `ChangeControlArrayAccessToAnnotatedControlVariableRector`
+
+- class: [`Rector\Nette\Rector\ArrayDimFetch\ChangeControlArrayAccessToAnnotatedControlVariableRector`](/../master/rules/nette/src/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector.php)
+- [test fixtures](/../master/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/Fixture)
+
+Change magic `$this["some_component"]` to variable assign with @var annotation
+
+```diff
+ use Nette\Application\UI\Presenter;
+ use Nette\Application\UI\Form;
+
+ final class SomePresenter extends Presenter
+ {
+ public function run()
+ {
+- if ($this['some_form']->isSubmitted()) {
++ /** @var \Nette\Application\UI\Form $someForm */
++ $someForm = $this['some_form'];
++ if ($someForm->isSubmitted()) {
+ }
+ }
+
+ protected function createComponentSomeForm()
+ {
+ return new Form();
+ }
+ }
+```
+
+
+
### `ChangeFormArrayAccessToAnnotatedControlVariableRector`
- class: [`Rector\Nette\Rector\ArrayDimFetch\ChangeFormArrayAccessToAnnotatedControlVariableRector`](/../master/rules/nette/src/Rector/ArrayDimFetch/ChangeFormArrayAccessToAnnotatedControlVariableRector.php)
diff --git a/packages/anonymous-class/config/config.php b/packages/anonymous-class/config/config.php
new file mode 100644
index 00000000000..6566daa42e2
--- /dev/null
+++ b/packages/anonymous-class/config/config.php
@@ -0,0 +1,15 @@
+services();
+
+ $services->defaults()
+ ->autowire()
+ ->public();
+
+ $services->load('Rector\AnonymousClass\\', __DIR__ . '/../src');
+};
diff --git a/packages/anonymous-class/src/NodeAnalyzer/ClassNodeAnalyzer.php b/packages/anonymous-class/src/NodeAnalyzer/ClassNodeAnalyzer.php
new file mode 100644
index 00000000000..7bc9363d481
--- /dev/null
+++ b/packages/anonymous-class/src/NodeAnalyzer/ClassNodeAnalyzer.php
@@ -0,0 +1,38 @@
+nodeNameResolver = $nodeNameResolver;
+ }
+
+ public function isAnonymousClass(Node $node): bool
+ {
+ if (! $node instanceof Class_) {
+ return false;
+ }
+
+ $className = $this->nodeNameResolver->getName($node);
+ if ($className === null) {
+ return true;
+ }
+
+ // match PHPStan pattern for anonymous classes
+ return (bool) Strings::match($className, '#AnonymousClass\w+$#');
+ }
+}
diff --git a/packages/node-type-resolver/src/NodeTypeResolver.php b/packages/node-type-resolver/src/NodeTypeResolver.php
index bbc6094c429..ce4738e59f0 100644
--- a/packages/node-type-resolver/src/NodeTypeResolver.php
+++ b/packages/node-type-resolver/src/NodeTypeResolver.php
@@ -12,7 +12,6 @@ use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\New_;
use PhpParser\Node\Param;
use PhpParser\Node\Scalar;
-use PhpParser\Node\Stmt\Class_;
use PHPStan\Analyser\Scope;
use PHPStan\Type\ArrayType;
use PHPStan\Type\FloatType;
@@ -25,12 +24,13 @@ use PHPStan\Type\Type;
use PHPStan\Type\TypeUtils;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
+use Rector\AnonymousClass\NodeAnalyzer\ClassNodeAnalyzer;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\NodeNameResolver\NodeNameResolver;
use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeCorrector\ParentClassesInterfacesAndUsedTraitsCorrector;
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
+use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
use Rector\TypeDeclaration\PHPStan\Type\ObjectTypeSpecifier;
final class NodeTypeResolver
@@ -40,11 +40,6 @@ final class NodeTypeResolver
*/
private $nodeTypeResolvers = [];
- /**
- * @var NodeNameResolver
- */
- private $nodeNameResolver;
-
/**
* @var ObjectTypeSpecifier
*/
@@ -60,23 +55,34 @@ final class NodeTypeResolver
*/
private $parentClassesInterfacesAndUsedTraitsCorrector;
+ /**
+ * @var TypeUnwrapper
+ */
+ private $typeUnwrapper;
+
+ /**
+ * @var ClassNodeAnalyzer
+ */
+ private $classNodeAnalyzer;
+
/**
* @param NodeTypeResolverInterface[] $nodeTypeResolvers
*/
public function __construct(
- NodeNameResolver $nodeNameResolver,
ObjectTypeSpecifier $objectTypeSpecifier,
ParentClassesInterfacesAndUsedTraitsCorrector $parentClassesInterfacesAndUsedTraitsCorrector,
+ TypeUnwrapper $typeUnwrapper,
+ ClassNodeAnalyzer $classNodeAnalyzer,
array $nodeTypeResolvers
) {
- $this->nodeNameResolver = $nodeNameResolver;
-
foreach ($nodeTypeResolvers as $nodeTypeResolver) {
$this->addNodeTypeResolver($nodeTypeResolver);
}
$this->objectTypeSpecifier = $objectTypeSpecifier;
$this->parentClassesInterfacesAndUsedTraitsCorrector = $parentClassesInterfacesAndUsedTraitsCorrector;
+ $this->typeUnwrapper = $typeUnwrapper;
+ $this->classNodeAnalyzer = $classNodeAnalyzer;
}
/**
@@ -166,7 +172,7 @@ final class NodeTypeResolver
return new MixedType();
}
- if ($node instanceof New_ && $this->isAnonymousClass($node->class)) {
+ if ($node instanceof New_ && $this->classNodeAnalyzer->isAnonymousClass($node->class)) {
return new ObjectWithoutClassType();
}
@@ -178,6 +184,48 @@ final class NodeTypeResolver
return $this->objectTypeSpecifier->narrowToFullyQualifiedOrAlaisedObjectType($node, $staticType);
}
+ public function isNumberType(Node $node): bool
+ {
+ return $this->isStaticType($node, IntegerType::class) || $this->isStaticType($node, FloatType::class);
+ }
+
+ public function isStaticType(Node $node, string $staticTypeClass): bool
+ {
+ if (! is_a($staticTypeClass, Type::class, true)) {
+ throw new ShouldNotHappenException(sprintf(
+ '"%s" in "%s()" must be type of "%s"',
+ $staticTypeClass,
+ __METHOD__,
+ Type::class
+ ));
+ }
+
+ return is_a($this->resolve($node), $staticTypeClass);
+ }
+
+ /**
+ * @param ObjectType|string $desiredType
+ */
+ public function isObjectTypeOrNullableObjectType(Node $node, $desiredType): bool
+ {
+ if ($this->isObjectType($node, $desiredType)) {
+ return true;
+ }
+
+ $nodeType = $this->getStaticType($node);
+ if (! $nodeType instanceof UnionType) {
+ return false;
+ }
+
+ $unwrappedNodeType = $this->typeUnwrapper->unwrapNullableType($nodeType);
+ if (! $unwrappedNodeType instanceof TypeWithClassName) {
+ return false;
+ }
+
+ $desiredTypeString = $desiredType instanceof ObjectType ? $desiredType->getClassName() : $desiredType;
+ return is_a($unwrappedNodeType->getClassName(), $desiredTypeString, true);
+ }
+
public function isNullableObjectType(Node $node): bool
{
$nodeType = $this->resolve($node);
@@ -203,25 +251,6 @@ final class NodeTypeResolver
return false;
}
- public function isNumberType(Node $node): bool
- {
- return $this->isStaticType($node, IntegerType::class) || $this->isStaticType($node, FloatType::class);
- }
-
- public function isStaticType(Node $node, string $staticTypeClass): bool
- {
- if (! is_a($staticTypeClass, Type::class, true)) {
- throw new ShouldNotHappenException(sprintf(
- '"%s" in "%s()" must be type of "%s"',
- $staticTypeClass,
- __METHOD__,
- Type::class
- ));
- }
-
- return is_a($this->resolve($node), $staticTypeClass);
- }
-
private function addNodeTypeResolver(NodeTypeResolverInterface $nodeTypeResolver): void
{
foreach ($nodeTypeResolver->getNodeClasses() as $nodeClass) {
@@ -296,7 +325,7 @@ final class NodeTypeResolver
}
// skip anonymous classes, ref https://github.com/rectorphp/rector/issues/1574
- if ($node instanceof New_ && $this->isAnonymousClass($node->class)) {
+ if ($node instanceof New_ && $this->classNodeAnalyzer->isAnonymousClass($node->class)) {
return new ObjectWithoutClassType();
}
@@ -331,17 +360,6 @@ final class NodeTypeResolver
return new ArrayType(new MixedType(), new MixedType());
}
- private function isAnonymousClass(Node $node): bool
- {
- if (! $node instanceof Class_) {
- return false;
- }
-
- $className = $this->nodeNameResolver->getName($node);
-
- return $className === null || Strings::contains($className, 'AnonymousClass');
- }
-
private function resolveByNodeTypeResolvers(Node $node): ?Type
{
foreach ($this->nodeTypeResolvers as $nodeClass => $nodeTypeResolver) {
diff --git a/packages/phpstan-static-type-mapper/src/Utils/TypeUnwrapper.php b/packages/phpstan-static-type-mapper/src/Utils/TypeUnwrapper.php
index 818750671b0..10972675164 100644
--- a/packages/phpstan-static-type-mapper/src/Utils/TypeUnwrapper.php
+++ b/packages/phpstan-static-type-mapper/src/Utils/TypeUnwrapper.php
@@ -8,6 +8,7 @@ use PHPStan\Type\NullType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use PHPStan\Type\UnionType;
+use Rector\PHPStan\TypeFactoryStaticHelper;
final class TypeUnwrapper
{
@@ -51,4 +52,22 @@ final class TypeUnwrapper
return $type;
}
+
+ /**
+ * @return Type|UnionType
+ */
+ public function removeNullTypeFromUnionType(UnionType $unionType): Type
+ {
+ $unionedTypesWithoutNullType = [];
+
+ foreach ($unionType->getTypes() as $type) {
+ if ($type instanceof UnionType) {
+ continue;
+ }
+
+ $unionedTypesWithoutNullType[] = $type;
+ }
+
+ return TypeFactoryStaticHelper::createUnionObjectType($unionedTypesWithoutNullType);
+ }
}
diff --git a/packages/post-rector/src/Collector/NodesToAddCollector.php b/packages/post-rector/src/Collector/NodesToAddCollector.php
index b1b40301455..bac96c84bb5 100644
--- a/packages/post-rector/src/Collector/NodesToAddCollector.php
+++ b/packages/post-rector/src/Collector/NodesToAddCollector.php
@@ -9,6 +9,7 @@ use PhpParser\Node\Expr;
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\If_;
+use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
use Rector\PostRector\Contract\Collector\NodeCollectorInterface;
@@ -41,6 +42,11 @@ final class NodesToAddCollector implements NodeCollectorInterface
public function addNodeBeforeNode(Node $addedNode, Node $positionNode): void
{
+ if ($positionNode->getAttributes() === []) {
+ $message = sprintf('Switch arguments in "%s()" method', __METHOD__);
+ throw new ShouldNotHappenException($message);
+ }
+
$position = $this->resolveNearestExpressionPosition($positionNode);
$this->nodesToAddBefore[$position][] = $this->wrapToExpression($addedNode);
}
diff --git a/rules/code-quality/src/Rector/If_/SimplifyIfReturnBoolRector.php b/rules/code-quality/src/Rector/If_/SimplifyIfReturnBoolRector.php
index 6642d09e748..4fed24102e3 100644
--- a/rules/code-quality/src/Rector/If_/SimplifyIfReturnBoolRector.php
+++ b/rules/code-quality/src/Rector/If_/SimplifyIfReturnBoolRector.php
@@ -23,7 +23,7 @@ use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PHPStan\Type\StaticTypeAnalyzer;
-use Rector\PHPStan\TypeFactoryStaticHelper;
+use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper;
/**
* @see \Rector\CodeQuality\Tests\Rector\If_\SimplifyIfReturnBoolRector\SimplifyIfReturnBoolRectorTest
@@ -40,12 +40,19 @@ final class SimplifyIfReturnBoolRector extends AbstractRector
*/
private $mergedNodeCommentPreserver;
+ /**
+ * @var TypeUnwrapper
+ */
+ private $typeUnwrapper;
+
public function __construct(
MergedNodeCommentPreserver $mergedNodeCommentPreserver,
+ TypeUnwrapper $typeUnwrapper,
StaticTypeAnalyzer $staticTypeAnalyzer
) {
- $this->staticTypeAnalyzer = $staticTypeAnalyzer;
$this->mergedNodeCommentPreserver = $mergedNodeCommentPreserver;
+ $this->typeUnwrapper = $typeUnwrapper;
+ $this->staticTypeAnalyzer = $staticTypeAnalyzer;
}
public function getDefinition(): RectorDefinition
@@ -205,7 +212,7 @@ PHP
$exprStaticType = $this->getStaticType($expr);
// if we remove null type, still has to be trueable
if ($exprStaticType instanceof UnionType) {
- $unionTypeWithoutNullType = $this->removeNullTypeFromUnionType($exprStaticType);
+ $unionTypeWithoutNullType = $this->typeUnwrapper->removeNullTypeFromUnionType($exprStaticType);
if ($this->staticTypeAnalyzer->isAlwaysTruableType($unionTypeWithoutNullType)) {
return new NotIdentical($expr, $this->createNull());
}
@@ -221,23 +228,6 @@ PHP
return new Bool_($expr);
}
- /**
- * @return Type|UnionType
- */
- private function removeNullTypeFromUnionType(UnionType $unionType): Type
- {
- $unionedTypesWithoutNullType = [];
- foreach ($unionType->getTypes() as $type) {
- if ($type instanceof UnionType) {
- continue;
- }
-
- $unionedTypesWithoutNullType[] = $type;
- }
-
- return TypeFactoryStaticHelper::createUnionObjectType($unionedTypesWithoutNullType);
- }
-
private function isBoolCastNeeded(Expr $expr): bool
{
if ($expr instanceof BooleanNot) {
diff --git a/src/Naming/NamespaceMatcher.php b/rules/naming/src/NamespaceMatcher.php
similarity index 95%
rename from src/Naming/NamespaceMatcher.php
rename to rules/naming/src/NamespaceMatcher.php
index b5c20e2a52d..c9660e695b8 100644
--- a/src/Naming/NamespaceMatcher.php
+++ b/rules/naming/src/NamespaceMatcher.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Rector\Core\Naming;
+namespace Rector\Naming;
use Nette\Utils\Strings;
use Rector\Core\ValueObject\RenamedNamespaceValueObject;
diff --git a/rules/nette/src/DocBlock/VarAnnotationManipulator.php b/rules/nette/src/DocBlock/VarAnnotationManipulator.php
new file mode 100644
index 00000000000..a8850c5340b
--- /dev/null
+++ b/rules/nette/src/DocBlock/VarAnnotationManipulator.php
@@ -0,0 +1,72 @@
+phpDocInfoFactory = $phpDocInfoFactory;
+ }
+
+ public function decorateNodeWithInlineVarType(
+ Node $node,
+ TypeWithClassName $controlTypeWithClassName,
+ string $variableName
+ ): void {
+ $phpDocInfo = $this->resolvePhpDocInfo($node);
+
+ // already done
+ if ($phpDocInfo->getVarTagValue() !== null) {
+ return;
+ }
+
+ $attributeAwareFullyQualifiedIdentifierTypeNode = new AttributeAwareFullyQualifiedIdentifierTypeNode(
+ $controlTypeWithClassName->getClassName()
+ );
+
+ $attributeAwareVarTagValueNode = new AttributeAwareVarTagValueNode(
+ $attributeAwareFullyQualifiedIdentifierTypeNode,
+ '$' . $variableName,
+ ''
+ );
+
+ $phpDocInfo->addTagValueNode($attributeAwareVarTagValueNode);
+ }
+
+ private function resolvePhpDocInfo(Node $node): PhpDocInfo
+ {
+ $currentStmt = $node->getAttribute(AttributeKey::CURRENT_STATEMENT);
+ if ($currentStmt instanceof Expression) {
+ /** @var PhpDocInfo|null $phpDocInfo */
+ $phpDocInfo = $currentStmt->getAttribute(AttributeKey::PHP_DOC_INFO);
+ } else {
+ /** @var PhpDocInfo|null $phpDocInfo */
+ $phpDocInfo = $node->getAttribute(AttributeKey::PHP_DOC_INFO);
+ }
+
+ if ($phpDocInfo === null) {
+ $phpDocInfo = $this->phpDocInfoFactory->createEmpty($node);
+ }
+
+ $phpDocInfo->makeSingleLined();
+
+ return $phpDocInfo;
+ }
+}
diff --git a/rules/nette/src/FormControlTypeResolver/ArrayDimFetchControlTypeResolver.php b/rules/nette/src/FormControlTypeResolver/ArrayDimFetchControlTypeResolver.php
new file mode 100644
index 00000000000..b40440c18da
--- /dev/null
+++ b/rules/nette/src/FormControlTypeResolver/ArrayDimFetchControlTypeResolver.php
@@ -0,0 +1,109 @@
+functionLikeParsedNodesFinder = $functionLikeParsedNodesFinder;
+ $this->controlDimFetchAnalyzer = $controlDimFetchAnalyzer;
+ $this->nodeTypeResolver = $nodeTypeResolver;
+ $this->netteControlNaming = $netteControlNaming;
+ $this->returnTypeInferer = $returnTypeInferer;
+ }
+
+ /**
+ * @return array
+ */
+ public function resolve(Node $node): array
+ {
+ if (! $node instanceof ArrayDimFetch) {
+ return [];
+ }
+
+ $controlShortName = $this->controlDimFetchAnalyzer->matchName($node);
+ if ($controlShortName === null) {
+ return [];
+ }
+
+ $createComponentClassMethod = $this->matchCreateComponentClassMethod($node, $controlShortName);
+ if ($createComponentClassMethod === null) {
+ return [];
+ }
+
+ $createComponentClassMethodReturnType = $this->returnTypeInferer->inferFunctionLike(
+ $createComponentClassMethod
+ );
+
+ if (! $createComponentClassMethodReturnType instanceof TypeWithClassName) {
+ return [];
+ }
+
+ return [
+ $controlShortName => $createComponentClassMethodReturnType->getClassName(),
+ ];
+ }
+
+ private function matchCreateComponentClassMethod(
+ ArrayDimFetch $arrayDimFetch,
+ string $controlShortName
+ ): ?ClassMethod {
+ $callerType = $this->nodeTypeResolver->getStaticType($arrayDimFetch->var);
+ if (! $callerType instanceof TypeWithClassName) {
+ return null;
+ }
+
+ $createComponentClassMethodName = $this->netteControlNaming->createCreateComponentClassMethodName(
+ $controlShortName
+ );
+
+ return $this->functionLikeParsedNodesFinder->findClassMethod(
+ $createComponentClassMethodName,
+ $callerType->getClassName()
+ );
+ }
+}
diff --git a/rules/nette/src/Naming/NetteControlNaming.php b/rules/nette/src/Naming/NetteControlNaming.php
new file mode 100644
index 00000000000..f81019f7832
--- /dev/null
+++ b/rules/nette/src/Naming/NetteControlNaming.php
@@ -0,0 +1,26 @@
+createVariableName($shortName));
+ }
+}
diff --git a/rules/nette/src/NodeAnalyzer/ControlDimFetchAnalyzer.php b/rules/nette/src/NodeAnalyzer/ControlDimFetchAnalyzer.php
new file mode 100644
index 00000000000..a3cc0603b8c
--- /dev/null
+++ b/rules/nette/src/NodeAnalyzer/ControlDimFetchAnalyzer.php
@@ -0,0 +1,50 @@
+nodeTypeResolver = $nodeTypeResolver;
+ }
+
+ public function matchName(Node $node): ?string
+ {
+ if (! $node instanceof ArrayDimFetch) {
+ return null;
+ }
+
+ if (! $this->isContainerVariable($node->var)) {
+ return null;
+ }
+
+ if (! $node->dim instanceof String_) {
+ return null;
+ }
+
+ return $node->dim->value;
+ }
+
+ private function isContainerVariable(Node $node): bool
+ {
+ if (! $node instanceof Variable) {
+ return false;
+ }
+
+ return $this->nodeTypeResolver->isObjectTypeOrNullableObjectType($node, 'Nette\ComponentModel\IContainer');
+ }
+}
diff --git a/rules/nette/src/NodeResolver/FormVariableInputNameTypeResolver.php b/rules/nette/src/NodeResolver/FormVariableInputNameTypeResolver.php
index 66e6d49db88..80a62957ef4 100644
--- a/rules/nette/src/NodeResolver/FormVariableInputNameTypeResolver.php
+++ b/rules/nette/src/NodeResolver/FormVariableInputNameTypeResolver.php
@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Rector\Nette\NodeResolver;
-use PhpParser\Node\Expr\Variable;
+use PhpParser\Node\Expr;
use Rector\Core\Exception\NotImplementedYetException;
use Rector\Core\Exception\ShouldNotHappenException;
@@ -38,14 +38,13 @@ final class FormVariableInputNameTypeResolver
$this->methodNamesByInputNamesResolver = $methodNamesByInputNamesResolver;
}
- public function resolveControlTypeByInputName(Variable $formVariable, string $inputName): string
+ public function resolveControlTypeByInputName(Expr $formOrControlExpr, string $inputName): string
{
- $methodNamesByInputNames = $this->methodNamesByInputNamesResolver->resolveExpr($formVariable);
+ $methodNamesByInputNames = $this->methodNamesByInputNamesResolver->resolveExpr($formOrControlExpr);
$formAddMethodName = $methodNamesByInputNames[$inputName] ?? null;
-
if ($formAddMethodName === null) {
- $message = sprintf('Not found for "%s" input name', $inputName);
+ $message = sprintf('Type was not found for "%s" input name', $inputName);
throw new ShouldNotHappenException($message);
}
diff --git a/rules/nette/src/NodeResolver/MethodNamesByInputNamesResolver.php b/rules/nette/src/NodeResolver/MethodNamesByInputNamesResolver.php
index b12ec27c883..b1c328bd9ce 100644
--- a/rules/nette/src/NodeResolver/MethodNamesByInputNamesResolver.php
+++ b/rules/nette/src/NodeResolver/MethodNamesByInputNamesResolver.php
@@ -38,7 +38,6 @@ final class MethodNamesByInputNamesResolver
foreach ($this->formControlTypeResolvers as $formControlTypeResolver) {
$currentMethodNamesByInputNames = $formControlTypeResolver->resolve($node);
-
$methodNamesByInputNames = array_merge($methodNamesByInputNames, $currentMethodNamesByInputNames);
}
diff --git a/rules/nette/src/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector.php b/rules/nette/src/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector.php
new file mode 100644
index 00000000000..61317ea2923
--- /dev/null
+++ b/rules/nette/src/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector.php
@@ -0,0 +1,195 @@
+controlDimFetchAnalyzer = $controlDimFetchAnalyzer;
+ $this->netteControlNaming = $netteControlNaming;
+ $this->varAnnotationManipulator = $varAnnotationManipulator;
+ $this->methodNamesByInputNamesResolver = $methodNamesByInputNamesResolver;
+ }
+
+ public function getDefinition(): RectorDefinition
+ {
+ return new RectorDefinition('Change magic $this["some_component"] to variable assign with @var annotation', [
+ new CodeSample(
+ <<<'PHP'
+use Nette\Application\UI\Presenter;
+use Nette\Application\UI\Form;
+
+final class SomePresenter extends Presenter
+{
+ public function run()
+ {
+ if ($this['some_form']->isSubmitted()) {
+ }
+ }
+
+ protected function createComponentSomeForm()
+ {
+ return new Form();
+ }
+}
+PHP
+,
+ <<<'PHP'
+use Nette\Application\UI\Presenter;
+use Nette\Application\UI\Form;
+
+final class SomePresenter extends Presenter
+{
+ public function run()
+ {
+ /** @var \Nette\Application\UI\Form $someForm */
+ $someForm = $this['some_form'];
+ if ($someForm->isSubmitted()) {
+ }
+ }
+
+ protected function createComponentSomeForm()
+ {
+ return new Form();
+ }
+}
+PHP
+
+ ),
+ ]);
+ }
+
+ /**
+ * @return string[]
+ */
+ public function getNodeTypes(): array
+ {
+ return [ArrayDimFetch::class];
+ }
+
+ /**
+ * @param ArrayDimFetch $node
+ */
+ public function refactor(Node $node): ?Node
+ {
+ $controlName = $this->controlDimFetchAnalyzer->matchName($node);
+ if ($controlName === null) {
+ return null;
+ }
+
+ $variableName = $this->netteControlNaming->createVariableName($controlName);
+
+ $controlObjectType = $this->resolveControlType($node, $controlName);
+ $this->addAssignExpressionForFirstCase($variableName, $node, $controlObjectType);
+
+ return new Variable($variableName);
+ }
+
+ private function createAssignExpression(string $variableName, ArrayDimFetch $arrayDimFetch): Expression
+ {
+ $variable = new Variable($variableName);
+ $assignedDimFetch = clone $arrayDimFetch;
+ $assign = new Assign($variable, $assignedDimFetch);
+
+ return new Expression($assign);
+ }
+
+ private function addAssignExpressionForFirstCase(
+ string $variableName,
+ ArrayDimFetch $arrayDimFetch,
+ ObjectType $controlObjectType
+ ): void {
+ /** @var ClassMethod|null $classMethod */
+ $classMethod = $arrayDimFetch->getAttribute(AttributeKey::METHOD_NODE);
+ if ($classMethod !== null) {
+ $classMethodObjectHash = spl_object_hash($classMethod);
+ if (in_array($classMethodObjectHash, $this->alreadyInitializedAssignsClassMethodObjectHashes, true)) {
+ return;
+ }
+
+ $this->alreadyInitializedAssignsClassMethodObjectHashes[] = $classMethodObjectHash;
+ }
+
+ $assignExpression = $this->createAssignExpression($variableName, $arrayDimFetch);
+
+ $this->varAnnotationManipulator->decorateNodeWithInlineVarType(
+ $assignExpression,
+ $controlObjectType,
+ $variableName
+ );
+
+ $currentStatement = $arrayDimFetch->getAttribute(AttributeKey::CURRENT_STATEMENT);
+ $this->addNodeBeforeNode($assignExpression, $currentStatement);
+ }
+
+ private function resolveControlType(ArrayDimFetch $arrayDimFetch, string $controlName): ObjectType
+ {
+ $controlTypes = $this->methodNamesByInputNamesResolver->resolveExpr($arrayDimFetch);
+ if ($controlTypes === []) {
+ throw new NotImplementedYetException();
+ }
+
+ if (! isset($controlTypes[$controlName])) {
+ throw new ShouldNotHappenException();
+ }
+
+ $controlType = $controlTypes[$controlName];
+
+ return new ObjectType($controlType);
+ }
+}
diff --git a/rules/nette/src/Rector/ArrayDimFetch/ChangeFormArrayAccessToAnnotatedControlVariableRector.php b/rules/nette/src/Rector/ArrayDimFetch/ChangeFormArrayAccessToAnnotatedControlVariableRector.php
index 46866824a73..ad9991de8f1 100644
--- a/rules/nette/src/Rector/ArrayDimFetch/ChangeFormArrayAccessToAnnotatedControlVariableRector.php
+++ b/rules/nette/src/Rector/ArrayDimFetch/ChangeFormArrayAccessToAnnotatedControlVariableRector.php
@@ -8,15 +8,15 @@ use PhpParser\Node;
use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\Variable;
-use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\Expression;
-use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
-use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareFullyQualifiedIdentifierTypeNode;
-use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
+use PHPStan\Type\ObjectType;
+use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
-use Rector\Core\Util\StaticRectorStrings;
+use Rector\Nette\DocBlock\VarAnnotationManipulator;
+use Rector\Nette\Naming\NetteControlNaming;
+use Rector\Nette\NodeAnalyzer\ControlDimFetchAnalyzer;
use Rector\Nette\NodeResolver\FormVariableInputNameTypeResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -32,9 +32,31 @@ final class ChangeFormArrayAccessToAnnotatedControlVariableRector extends Abstra
*/
private $formVariableInputNameTypeResolver;
- public function __construct(FormVariableInputNameTypeResolver $formVariableInputNameTypeResolver)
- {
+ /**
+ * @var ControlDimFetchAnalyzer
+ */
+ private $controlDimFetchAnalyzer;
+
+ /**
+ * @var NetteControlNaming
+ */
+ private $netteControlNaming;
+
+ /**
+ * @var VarAnnotationManipulator
+ */
+ private $varAnnotationManipulator;
+
+ public function __construct(
+ FormVariableInputNameTypeResolver $formVariableInputNameTypeResolver,
+ ControlDimFetchAnalyzer $controlDimFetchAnalyzer,
+ NetteControlNaming $netteControlNaming,
+ VarAnnotationManipulator $varAnnotationManipulator
+ ) {
$this->formVariableInputNameTypeResolver = $formVariableInputNameTypeResolver;
+ $this->controlDimFetchAnalyzer = $controlDimFetchAnalyzer;
+ $this->netteControlNaming = $netteControlNaming;
+ $this->varAnnotationManipulator = $varAnnotationManipulator;
}
public function getDefinition(): RectorDefinition
@@ -90,8 +112,8 @@ PHP
*/
public function refactor(Node $node): ?Node
{
- $dimString = $this->matchNetteFormArrayDimString($node);
- if ($dimString === null) {
+ $inputName = $this->controlDimFetchAnalyzer->matchName($node);
+ if ($inputName === null) {
return null;
}
@@ -99,8 +121,7 @@ PHP
return null;
}
- $inputName = $this->getValue($dimString);
- $controlVariableName = $this->createControlVariableName($inputName);
+ $controlVariableName = $this->netteControlNaming->createVariableName($inputName);
$controlVariableToFormDimFetchAssign = new Assign(new Variable($controlVariableName), clone $node);
$assignExpression = new Expression($controlVariableToFormDimFetchAssign);
@@ -114,52 +135,23 @@ PHP
$inputName
);
- $this->addVarTag($controlVariableToFormDimFetchAssign, $assignExpression, $controlVariableName, $controlType);
+ $formVariableName = $this->getName($formVariable);
+ if ($formVariableName === null) {
+ throw new ShouldNotHappenException();
+ }
+
+ $controlObjectType = new ObjectType($controlType);
+ $this->varAnnotationManipulator->decorateNodeWithInlineVarType(
+ $assignExpression,
+ $controlObjectType,
+ $controlVariableName
+ );
$this->addNodeBeforeNode($assignExpression, $node);
return new Variable($controlVariableName);
}
- private function addVarTag(
- Assign $assign,
- Expression $assignExpression,
- string $controlName,
- string $controlType
- ): PhpDocInfo {
- $phpDocInfo = $this->phpDocInfoFactory->createEmpty($assignExpression);
-
- $varTagValueNode = new VarTagValueNode(
- new AttributeAwareFullyQualifiedIdentifierTypeNode($controlType),
- '$' . $controlName,
- ''
- );
-
- $phpDocInfo->addTagValueNode($varTagValueNode);
- $phpDocInfo->makeSingleLined();
-
- $assign->setAttribute(AttributeKey::PHP_DOC_INFO, $phpDocInfo);
-
- return $phpDocInfo;
- }
-
- private function matchNetteFormArrayDimString(ArrayDimFetch $arrayDimFetch): ?String_
- {
- if (! $arrayDimFetch->var instanceof Variable) {
- return null;
- }
-
- if (! $this->isObjectTypeOrNullableObjectType($arrayDimFetch->var, 'Nette\ComponentModel\IComponent')) {
- return null;
- }
-
- if (! $arrayDimFetch->dim instanceof String_) {
- return null;
- }
-
- return $arrayDimFetch->dim;
- }
-
private function isBeingAssignedOrInitialized(ArrayDimFetch $arrayDimFetch): bool
{
$parent = $arrayDimFetch->getAttribute(AttributeKey::PARENT_NODE);
@@ -173,9 +165,4 @@ PHP
return $parent->expr === $arrayDimFetch;
}
-
- private function createControlVariableName(string $inputName): string
- {
- return StaticRectorStrings::underscoreToPascalCase($inputName) . 'Control';
- }
}
diff --git a/rules/nette/src/Rector/Assign/MakeGetComponentAssignAnnotatedRector.php b/rules/nette/src/Rector/Assign/MakeGetComponentAssignAnnotatedRector.php
index 786fbefa49a..9075b043af8 100644
--- a/rules/nette/src/Rector/Assign/MakeGetComponentAssignAnnotatedRector.php
+++ b/rules/nette/src/Rector/Assign/MakeGetComponentAssignAnnotatedRector.php
@@ -11,20 +11,17 @@ use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Scalar\String_;
-use PhpParser\Node\Stmt\Expression;
use PHPStan\Analyser\Scope;
-use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
-use Rector\AttributeAwarePhpDoc\Ast\Type\AttributeAwareFullyQualifiedIdentifierTypeNode;
-use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
+use Rector\Nette\DocBlock\VarAnnotationManipulator;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
@@ -34,6 +31,16 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
*/
final class MakeGetComponentAssignAnnotatedRector extends AbstractRector
{
+ /**
+ * @var VarAnnotationManipulator
+ */
+ private $varAnnotationManipulator;
+
+ public function __construct(VarAnnotationManipulator $varAnnotationManipulator)
+ {
+ $this->varAnnotationManipulator = $varAnnotationManipulator;
+ }
+
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Add doc type for magic $control->getComponent(...) assign', [
@@ -125,48 +132,15 @@ PHP
}
$controlType = $this->resolveControlType($node);
- if ($controlType instanceof MixedType) {
+ if (! $controlType instanceof TypeWithClassName) {
return null;
}
- $phpDocInfo = $this->resolvePhpDocInfo($node);
- if ($phpDocInfo->getVarTagValue() !== null) {
- return null;
- }
-
- $attributeAwareFullyQualifiedIdentifierTypeNode = new AttributeAwareFullyQualifiedIdentifierTypeNode(
- $controlType->getClassName()
- );
- $varTagValueNode = new VarTagValueNode(
- $attributeAwareFullyQualifiedIdentifierTypeNode,
- '$' . $variableName,
- ''
- );
- $phpDocInfo->addTagValueNode($varTagValueNode);
+ $this->varAnnotationManipulator->decorateNodeWithInlineVarType($node, $controlType, $variableName);
return $node;
}
- private function resolvePhpDocInfo(Assign $assign): PhpDocInfo
- {
- $currentStmt = $assign->getAttribute(AttributeKey::CURRENT_STATEMENT);
- if ($currentStmt instanceof Expression) {
- /** @var PhpDocInfo|null $phpDocInfo */
- $phpDocInfo = $currentStmt->getAttribute(AttributeKey::PHP_DOC_INFO);
- } else {
- /** @var PhpDocInfo|null $phpDocInfo */
- $phpDocInfo = $assign->getAttribute(AttributeKey::PHP_DOC_INFO);
- }
-
- if ($phpDocInfo === null) {
- $phpDocInfo = $this->phpDocInfoFactory->createEmpty($assign);
- }
-
- $phpDocInfo->makeSingleLined();
-
- return $phpDocInfo;
- }
-
private function resolveCreateComponentMethodCallReturnType(MethodCall $methodCall): Type
{
/** @var Scope|null $scope */
diff --git a/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/ChangeControlArrayAccessToAnnotatedControlVariableRectorTest.php b/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/ChangeControlArrayAccessToAnnotatedControlVariableRectorTest.php
new file mode 100644
index 00000000000..769e08cc805
--- /dev/null
+++ b/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/ChangeControlArrayAccessToAnnotatedControlVariableRectorTest.php
@@ -0,0 +1,31 @@
+doTestFileInfo($fileInfo);
+ }
+
+ public function provideData(): Iterator
+ {
+ return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
+ }
+
+ protected function getRectorClass(): string
+ {
+ return ChangeControlArrayAccessToAnnotatedControlVariableRector::class;
+ }
+}
diff --git a/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/Fixture/fixture.php.inc b/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/Fixture/fixture.php.inc
new file mode 100644
index 00000000000..aa1e322a570
--- /dev/null
+++ b/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/Fixture/fixture.php.inc
@@ -0,0 +1,47 @@
+isSubmitted()) {
+ }
+ }
+
+ protected function createComponentSomeForm()
+ {
+ return new Form();
+ }
+}
+
+?>
+-----
+isSubmitted()) {
+ }
+ }
+
+ protected function createComponentSomeForm()
+ {
+ return new Form();
+ }
+}
+
+?>
diff --git a/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/Fixture/rename_nested_too.php.inc b/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/Fixture/rename_nested_too.php.inc
new file mode 100644
index 00000000000..90bc15a2092
--- /dev/null
+++ b/rules/nette/tests/Rector/ArrayDimFetch/ChangeControlArrayAccessToAnnotatedControlVariableRector/Fixture/rename_nested_too.php.inc
@@ -0,0 +1,49 @@
+isSubmitted()) {
+ return $this['some_form']->getValues();
+ }
+ }
+
+ protected function createComponentSomeForm()
+ {
+ return new Form();
+ }
+}
+
+?>
+-----
+isSubmitted()) {
+ return $someForm->getValues();
+ }
+ }
+
+ protected function createComponentSomeForm()
+ {
+ return new Form();
+ }
+}
+
+?>
diff --git a/rules/privatization/tests/Rector/ClassMethod/PrivatizeLocalOnlyMethodRector/Fixture/skip_anonymous_class.php.inc b/rules/privatization/tests/Rector/ClassMethod/PrivatizeLocalOnlyMethodRector/Fixture/skip_anonymous_class.php.inc
index ee1bf467c8e..0575d4e3bbd 100644
--- a/rules/privatization/tests/Rector/ClassMethod/PrivatizeLocalOnlyMethodRector/Fixture/skip_anonymous_class.php.inc
+++ b/rules/privatization/tests/Rector/ClassMethod/PrivatizeLocalOnlyMethodRector/Fixture/skip_anonymous_class.php.inc
@@ -6,6 +6,9 @@ use PhpParser\NodeTraverser;
class SkipAnonymousClass
{
+ /**
+ * @api
+ */
public function run()
{
$anonymousClass = new class() extends NodeTraverser
diff --git a/rules/renaming/src/Rector/Namespace_/RenameNamespaceRector.php b/rules/renaming/src/Rector/Namespace_/RenameNamespaceRector.php
index 42864368a1b..3e7fafefff5 100644
--- a/rules/renaming/src/Rector/Namespace_/RenameNamespaceRector.php
+++ b/rules/renaming/src/Rector/Namespace_/RenameNamespaceRector.php
@@ -11,11 +11,11 @@ use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\Node\Stmt\Use_;
-use Rector\Core\Naming\NamespaceMatcher;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\RectorDefinition\ConfiguredCodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\Core\ValueObject\RenamedNamespaceValueObject;
+use Rector\Naming\NamespaceMatcher;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php
index 89281181980..07dd8996d29 100644
--- a/src/Rector/AbstractRector.php
+++ b/src/Rector/AbstractRector.php
@@ -4,7 +4,6 @@ declare(strict_types=1);
namespace Rector\Core\Rector;
-use Nette\Utils\Strings;
use PhpParser\BuilderFactory;
use PhpParser\Node;
use PhpParser\Node\Expr;
@@ -13,11 +12,11 @@ use PhpParser\Node\Expr\Cast\Bool_;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt;
-use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Return_;
use PhpParser\NodeVisitorAbstract;
use PHPStan\Analyser\Scope;
+use Rector\AnonymousClass\NodeAnalyzer\ClassNodeAnalyzer;
use Rector\Core\Configuration\Option;
use Rector\Core\Contract\Rector\PhpRectorInterface;
use Rector\Core\Exclusion\ExclusionManager;
@@ -102,6 +101,11 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
*/
private $currentRectorProvider;
+ /**
+ * @var ClassNodeAnalyzer
+ */
+ private $classNodeAnalyzer;
+
/**
* @required
*/
@@ -113,7 +117,8 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
DocBlockManipulator $docBlockManipulator,
StaticTypeMapper $staticTypeMapper,
ParameterProvider $parameterProvider,
- CurrentRectorProvider $currentRectorProvider
+ CurrentRectorProvider $currentRectorProvider,
+ ClassNodeAnalyzer $classNodeAnalyzer
): void {
$this->symfonyStyle = $symfonyStyle;
$this->phpVersionProvider = $phpVersionProvider;
@@ -123,6 +128,7 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
$this->staticTypeMapper = $staticTypeMapper;
$this->parameterProvider = $parameterProvider;
$this->currentRectorProvider = $currentRectorProvider;
+ $this->classNodeAnalyzer = $classNodeAnalyzer;
}
public function beforeTraverse(array $nodes)
@@ -215,13 +221,7 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn
protected function isAnonymousClass(Node $node): bool
{
- if (! $node instanceof Class_) {
- return false;
- }
-
- $className = $this->nodeNameResolver->getName($node);
-
- return $className === null || Strings::contains($className, 'AnonymousClass');
+ return $this->classNodeAnalyzer->isAnonymousClass($node);
}
protected function createCountedValueName(string $countedValueName, ?Scope $scope): string
diff --git a/src/Rector/AbstractRector/NodeTypeResolverTrait.php b/src/Rector/AbstractRector/NodeTypeResolverTrait.php
index e67a9d59186..3b259761a18 100644
--- a/src/Rector/AbstractRector/NodeTypeResolverTrait.php
+++ b/src/Rector/AbstractRector/NodeTypeResolverTrait.php
@@ -14,7 +14,6 @@ use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
-use PHPStan\Type\UnionType;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\NodeTypeResolver\TypeAnalyzer\ArrayTypeAnalyzer;
@@ -90,25 +89,6 @@ trait NodeTypeResolverTrait
return $this->nodeTypeResolver->isObjectType($node, $type);
}
- /**
- * @param ObjectType|string $desiredType
- */
- protected function isObjectTypeOrNullableObjectType(Node $node, $desiredType): bool
- {
- if ($this->isNullableObjectType($node)) {
- /** @var UnionType $nodeType */
- $nodeType = $this->nodeTypeResolver->resolve($node);
-
- $nodeType = $this->typeUnwrapper->unwrapNullableType($nodeType);
- if ($nodeType instanceof TypeWithClassName) {
- $desiredTypeString = $desiredType instanceof ObjectType ? $desiredType->getClassName() : $desiredType;
- return is_a($nodeType->getClassName(), $desiredTypeString, true);
- }
- }
-
- return $this->nodeTypeResolver->isObjectType($node, $desiredType);
- }
-
/**
* @param string[]|ObjectType[] $requiredTypes
*/