diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/AddClosureParamTypeFromArgRectorTest.php b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/AddClosureParamTypeFromArgRectorTest.php deleted file mode 100644 index bb67c430001..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/AddClosureParamTypeFromArgRectorTest.php +++ /dev/null @@ -1,28 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/fixture.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/fixture.php.inc deleted file mode 100644 index f3b2d7f3a76..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/fixture.php.inc +++ /dev/null @@ -1,23 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/overrides_previous_type.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/overrides_previous_type.php.inc deleted file mode 100644 index 5e027c194a6..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/overrides_previous_type.php.inc +++ /dev/null @@ -1,21 +0,0 @@ - $var); - -?> ------ - $var); - -?> diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/simple_string.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/simple_string.php.inc deleted file mode 100644 index 6c4238629f7..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/simple_string.php.inc +++ /dev/null @@ -1,23 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/skip_if_calllike_arg_is_named.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/skip_if_calllike_arg_is_named.php.inc deleted file mode 100644 index b5d5f773460..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/skip_if_calllike_arg_is_named.php.inc +++ /dev/null @@ -1,7 +0,0 @@ - $var, callback: fn($var) => $var); diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/skip_if_non_functionlike_parameter_missing.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/skip_if_non_functionlike_parameter_missing.php.inc deleted file mode 100644 index a4665307ff9..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/skip_if_non_functionlike_parameter_missing.php.inc +++ /dev/null @@ -1,7 +0,0 @@ - 'test'); diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/skip_if_non_functionlike_parameters_in_method_call.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/skip_if_non_functionlike_parameters_in_method_call.php.inc deleted file mode 100644 index b6392720078..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Fixture/skip_if_non_functionlike_parameters_in_method_call.php.inc +++ /dev/null @@ -1,7 +0,0 @@ - $var); - -?> ------ - $var); - -?> diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Source/NonTargetedClass.php b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Source/NonTargetedClass.php deleted file mode 100644 index c8ea77b8f5a..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector/Source/NonTargetedClass.php +++ /dev/null @@ -1,8 +0,0 @@ -ruleWithConfiguration(AddClosureParamTypeFromArgRector::class, [ - new AddClosureParamTypeFromArg(SimpleContainer::class, 'someCall', 1, 0), - ]); - - $rectorConfig->phpVersion(PhpVersionFeature::MIXED_TYPE); -}; diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/AddClosureParamTypeFromObjectRectorTest.php b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/AddClosureParamTypeFromObjectRectorTest.php deleted file mode 100644 index f917e091800..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/AddClosureParamTypeFromObjectRectorTest.php +++ /dev/null @@ -1,28 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/fixture.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/fixture.php.inc deleted file mode 100644 index 460ad8285a1..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/fixture.php.inc +++ /dev/null @@ -1,23 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/overrides_previous_type.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/overrides_previous_type.php.inc deleted file mode 100644 index 162debdb415..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/overrides_previous_type.php.inc +++ /dev/null @@ -1,21 +0,0 @@ - $var); - -?> ------ - $var); - -?> diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/skip_if_calllike_arg_is_named.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/skip_if_calllike_arg_is_named.php.inc deleted file mode 100644 index 9bc78adc1ee..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/skip_if_calllike_arg_is_named.php.inc +++ /dev/null @@ -1,7 +0,0 @@ - $var, callback: fn($var) => $var); diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/skip_if_non_functionlike_parameter_missing.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/skip_if_non_functionlike_parameter_missing.php.inc deleted file mode 100644 index 4482214ba0c..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/skip_if_non_functionlike_parameter_missing.php.inc +++ /dev/null @@ -1,7 +0,0 @@ - 'test'); diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/skip_if_non_functionlike_parameters_in_method_call.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/skip_if_non_functionlike_parameters_in_method_call.php.inc deleted file mode 100644 index a6ffb56d782..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector/Fixture/skip_if_non_functionlike_parameters_in_method_call.php.inc +++ /dev/null @@ -1,7 +0,0 @@ -ruleWithConfiguration(AddClosureParamTypeFromObjectRector::class, [ - new AddClosureParamTypeFromObject(SimpleContainer::class, 'someCall', 1, 0), - ]); - - $rectorConfig->phpVersion(PhpVersionFeature::MIXED_TYPE); -}; diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRectorTest.php b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRectorTest.php deleted file mode 100644 index 5db3f901fc1..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRectorTest.php +++ /dev/null @@ -1,28 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/fixture.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/fixture.php.inc deleted file mode 100644 index ee754278dae..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/fixture.php.inc +++ /dev/null @@ -1,51 +0,0 @@ -someCall(function ($name) { - return $name; -}); - -(new SomeClass())->someCall(function ($name) { - return $name; -}); - -$var->someCall(fn ($name) => $name); - -SomeClassForNamed::someCall('a', 'b', callback: fn ($var) => $var); - -?> ------ -someCall(function (string $name) { - return $name; -}); - -(new SomeClass())->someCall(function (string $name) { - return $name; -}); - -$var->someCall(fn (string $name) => $name); - -SomeClassForNamed::someCall('a', 'b', callback: fn (string $var) => $var); - -?> diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/overrides_previous_type.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/overrides_previous_type.php.inc deleted file mode 100644 index d6c346a51ff..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/overrides_previous_type.php.inc +++ /dev/null @@ -1,19 +0,0 @@ - $var); - -?> ------ - $var); - -?> diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/skip_if_calllike_arg_is_named.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/skip_if_calllike_arg_is_named.php.inc deleted file mode 100644 index b8e32fd01c2..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/skip_if_calllike_arg_is_named.php.inc +++ /dev/null @@ -1,9 +0,0 @@ - $var, callback: fn($var) => $var); - -?> diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/skip_if_non_functionlike_parameter_missing.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/skip_if_non_functionlike_parameter_missing.php.inc deleted file mode 100644 index 6736220d6d8..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/skip_if_non_functionlike_parameter_missing.php.inc +++ /dev/null @@ -1,7 +0,0 @@ - 'test'); diff --git a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/skip_if_non_functionlike_parameters_in_method_call.php.inc b/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/skip_if_non_functionlike_parameters_in_method_call.php.inc deleted file mode 100644 index bc607559324..00000000000 --- a/rules-tests/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector/Fixture/skip_if_non_functionlike_parameters_in_method_call.php.inc +++ /dev/null @@ -1,7 +0,0 @@ -ruleWithConfiguration(AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector::class, [ - new AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration( - 'SomeNamespace\SomeClass', - 'someCall', - 0, - 0, - new StringType() - ), - new AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration( - 'SomeNamespace\SomeClassForNamed', - 'someCall', - 'callback', - 0, - new StringType() - ), - ]); - - $rectorConfig->phpVersion(PhpVersionFeature::MIXED_TYPE); -}; diff --git a/rules/Strict/Rector/BooleanNot/BooleanInBooleanNotRuleFixerRector.php b/rules/Strict/Rector/BooleanNot/BooleanInBooleanNotRuleFixerRector.php index eac390488fc..8a91cf2eab0 100644 --- a/rules/Strict/Rector/BooleanNot/BooleanInBooleanNotRuleFixerRector.php +++ b/rules/Strict/Rector/BooleanNot/BooleanInBooleanNotRuleFixerRector.php @@ -76,6 +76,6 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Expr { - throw new ShouldNotHappenException('This rule is deprecated as risky and not practical'); + throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated as risky and not practical', self::class)); } } diff --git a/rules/Strict/Rector/Ternary/BooleanInTernaryOperatorRuleFixerRector.php b/rules/Strict/Rector/Ternary/BooleanInTernaryOperatorRuleFixerRector.php index e72274af5f2..e5e5b62ddbd 100644 --- a/rules/Strict/Rector/Ternary/BooleanInTernaryOperatorRuleFixerRector.php +++ b/rules/Strict/Rector/Ternary/BooleanInTernaryOperatorRuleFixerRector.php @@ -67,6 +67,6 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Ternary { - throw new ShouldNotHappenException('This rule is deprecated as risky and not practical'); + throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated as risky and not practical', self::class)); } } diff --git a/rules/Strict/Rector/Ternary/DisallowedShortTernaryRuleFixerRector.php b/rules/Strict/Rector/Ternary/DisallowedShortTernaryRuleFixerRector.php index df2a9bd2940..07dc5d9dde9 100644 --- a/rules/Strict/Rector/Ternary/DisallowedShortTernaryRuleFixerRector.php +++ b/rules/Strict/Rector/Ternary/DisallowedShortTernaryRuleFixerRector.php @@ -70,6 +70,6 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Ternary { - throw new ShouldNotHappenException('This rule is deprecated as risky and not practical'); + throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated as risky and not practical', self::class)); } } diff --git a/rules/TypeDeclaration/NodeTypeAnalyzer/PropertyTypeDecorator.php b/rules/TypeDeclaration/NodeTypeAnalyzer/PropertyTypeDecorator.php index e9c37352efa..3ca5b32bcf2 100644 --- a/rules/TypeDeclaration/NodeTypeAnalyzer/PropertyTypeDecorator.php +++ b/rules/TypeDeclaration/NodeTypeAnalyzer/PropertyTypeDecorator.php @@ -9,19 +9,18 @@ use PhpParser\Node\Identifier; use PhpParser\Node\Name; use PhpParser\Node\Stmt\Property; +use PHPStan\Type\TypeCombinator; use PHPStan\Type\UnionType; use PHPStan\Type\VerbosityLevel; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; use Rector\Php\PhpVersionProvider; use Rector\PhpParser\Node\NodeFactory; -use Rector\PHPStanStaticTypeMapper\TypeAnalyzer\UnionTypeAnalyzer; use Rector\ValueObject\PhpVersionFeature; final readonly class PropertyTypeDecorator { public function __construct( - private UnionTypeAnalyzer $unionTypeAnalyzer, private PhpDocTypeChanger $phpDocTypeChanger, private PhpVersionProvider $phpVersionProvider, private NodeFactory $nodeFactory, @@ -35,7 +34,7 @@ public function decoratePropertyUnionType( PhpDocInfo $phpDocInfo, bool $changeVarTypeFallback = true ): void { - if (! $this->unionTypeAnalyzer->isNullable($unionType)) { + if (! TypeCombinator::containsNull($unionType)) { if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::UNION_TYPES)) { $property->type = $typeNode; return; diff --git a/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector.php b/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector.php index 732a414e555..c2ed06629e3 100644 --- a/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector.php +++ b/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromArgRector.php @@ -5,53 +5,22 @@ namespace Rector\TypeDeclaration\Rector\FunctionLike; use PhpParser\Node; -use PhpParser\Node\Arg; -use PhpParser\Node\Expr; -use PhpParser\Node\Expr\ArrowFunction; -use PhpParser\Node\Expr\Closure; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; -use PhpParser\Node\Identifier; -use PhpParser\Node\Name; -use PhpParser\Node\Param; -use PHPStan\Reflection\ReflectionProvider; -use PHPStan\Type\Constant\ConstantStringType; -use PHPStan\Type\Generic\GenericClassStringType; -use PHPStan\Type\ObjectType; -use PHPStan\Type\StringType; -use PHPStan\Type\Type; +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; use Rector\Contract\Rector\ConfigurableRectorInterface; -use Rector\NodeTypeResolver\TypeComparator\TypeComparator; -use Rector\PHPStanStaticTypeMapper\Enum\TypeKind; +use Rector\Exception\ShouldNotHappenException; use Rector\Rector\AbstractRector; -use Rector\StaticTypeMapper\StaticTypeMapper; use Rector\TypeDeclaration\ValueObject\AddClosureParamTypeFromArg; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Webmozart\Assert\Assert; /** - * @see \Rector\Tests\TypeDeclaration\Rector\FunctionLike\AddClosureParamTypeFromArgRector\AddClosureParamTypeFromArgRectorTest + * @deprecated as too specific and not useful in Rector core. Implement it locally instead if needed. */ -final class AddClosureParamTypeFromArgRector extends AbstractRector implements ConfigurableRectorInterface +final class AddClosureParamTypeFromArgRector extends AbstractRector implements ConfigurableRectorInterface, DeprecatedInterface { - /** - * @var int - */ - private const DEFAULT_CLOSURE_ARG_POSITION = 0; - - /** - * @var AddClosureParamTypeFromArg[] - */ - private array $addClosureParamTypeFromArgs = []; - - public function __construct( - private readonly TypeComparator $typeComparator, - private readonly StaticTypeMapper $staticTypeMapper, - private readonly ReflectionProvider $reflectionProvider - ) { - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Add closure param type based on known passed service/string types of method calls', [ @@ -84,23 +53,10 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - foreach ($this->addClosureParamTypeFromArgs as $addClosureParamTypeFromArg) { - if ($node instanceof MethodCall) { - $caller = $node->var; - } elseif ($node instanceof StaticCall) { - $caller = $node->class; - } else { - continue; - } - - if (! $this->isCallMatch($caller, $addClosureParamTypeFromArg, $node)) { - continue; - } - - return $this->processCallLike($node, $addClosureParamTypeFromArg); - } - - return null; + throw new ShouldNotHappenException(sprintf( + '"%s" rule is deprecated as too specific and not practical for general core rules', + self::class + )); } /** @@ -109,103 +65,5 @@ public function refactor(Node $node): ?Node public function configure(array $configuration): void { Assert::allIsAOf($configuration, AddClosureParamTypeFromArg::class); - - $this->addClosureParamTypeFromArgs = $configuration; - } - - private function processCallLike( - MethodCall|StaticCall $callLike, - AddClosureParamTypeFromArg $addClosureParamTypeFromArg - ): MethodCall|StaticCall|null { - if ($callLike->isFirstClassCallable()) { - return null; - } - - $callLikeArg = $callLike->args[$addClosureParamTypeFromArg->getCallLikePosition()] ?? null; - if (! $callLikeArg instanceof Arg) { - return null; - } - - // int positions shouldn't have names - if ($callLikeArg->name instanceof Identifier) { - return null; - } - - $functionLike = $callLikeArg->value; - if (! $functionLike instanceof Closure && ! $functionLike instanceof ArrowFunction) { - return null; - } - - if (! isset($functionLike->params[$addClosureParamTypeFromArg->getFunctionLikePosition()])) { - return null; - } - - $callLikeArg = $callLike->getArgs()[self::DEFAULT_CLOSURE_ARG_POSITION] ?? null; - if (! $callLikeArg instanceof Arg) { - return null; - } - - $hasChanged = $this->refactorParameter( - $functionLike->params[$addClosureParamTypeFromArg->getFunctionLikePosition()], - $callLikeArg, - ); - - if ($hasChanged) { - return $callLike; - } - - return null; - } - - private function refactorParameter(Param $param, Arg $arg): bool - { - $closureType = $this->resolveClosureType($arg->value); - if (! $closureType instanceof Type) { - return false; - } - - // already set → no change - if ($param->type instanceof Node) { - $currentParamType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($param->type); - if ($this->typeComparator->areTypesEqual($currentParamType, $closureType)) { - return false; - } - } - - $paramTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($closureType, TypeKind::PARAM); - $param->type = $paramTypeNode; - - return true; - } - - private function isCallMatch( - Name|Expr $caller, - AddClosureParamTypeFromArg $addClosureParamTypeFromArg, - StaticCall|MethodCall $call - ): bool { - if (! $this->isObjectType($caller, $addClosureParamTypeFromArg->getObjectType())) { - return false; - } - - return $this->isName($call->name, $addClosureParamTypeFromArg->getMethodName()); - } - - private function resolveClosureType(Expr $expr): ?Type - { - $exprType = $this->nodeTypeResolver->getType($expr); - - if ($exprType instanceof GenericClassStringType) { - return $exprType->getGenericType(); - } - - if ($exprType instanceof ConstantStringType) { - if ($this->reflectionProvider->hasClass($exprType->getValue())) { - return new ObjectType($exprType->getValue()); - } - - return new StringType(); - } - - return null; } } diff --git a/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector.php b/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector.php index 6a47127a7f2..87dfb94ce6b 100644 --- a/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector.php +++ b/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromObjectRector.php @@ -5,47 +5,22 @@ namespace Rector\TypeDeclaration\Rector\FunctionLike; use PhpParser\Node; -use PhpParser\Node\Arg; -use PhpParser\Node\Expr; -use PhpParser\Node\Expr\ArrowFunction; -use PhpParser\Node\Expr\Closure; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; -use PhpParser\Node\Identifier; -use PhpParser\Node\Name; -use PhpParser\Node\Param; -use PHPStan\Type\ObjectType; +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; use Rector\Contract\Rector\ConfigurableRectorInterface; -use Rector\NodeTypeResolver\TypeComparator\TypeComparator; -use Rector\PHPStanStaticTypeMapper\Enum\TypeKind; +use Rector\Exception\ShouldNotHappenException; use Rector\Rector\AbstractRector; -use Rector\StaticTypeMapper\StaticTypeMapper; use Rector\TypeDeclaration\ValueObject\AddClosureParamTypeFromObject; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Webmozart\Assert\Assert; /** - * @see \Rector\Tests\TypeDeclaration\Rector\FunctionLike\AddClosureParamTypeFromObjectRector\AddClosureParamTypeFromObjectRectorTest + * @deprecated as too specific and not useful in Rector core. Implement it locally instead if needed. */ -final class AddClosureParamTypeFromObjectRector extends AbstractRector implements ConfigurableRectorInterface +final class AddClosureParamTypeFromObjectRector extends AbstractRector implements ConfigurableRectorInterface, DeprecatedInterface { - /** - * @var int - */ - private const DEFAULT_CLOSURE_ARG_POSITION = 0; - - /** - * @var AddClosureParamTypeFromObject[] - */ - private array $addClosureParamTypeFromObjects = []; - - public function __construct( - private readonly TypeComparator $typeComparator, - private readonly StaticTypeMapper $staticTypeMapper - ) { - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Add closure param type based on the object of the method call', [ @@ -78,28 +53,10 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - foreach ($this->addClosureParamTypeFromObjects as $addClosureParamTypeFromObject) { - if ($node instanceof MethodCall) { - $caller = $node->var; - } elseif ($node instanceof StaticCall) { - $caller = $node->class; - } else { - continue; - } - - if (! $this->isCallMatch($caller, $addClosureParamTypeFromObject, $node)) { - continue; - } - - $type = $this->getType($caller); - if (! $type instanceof ObjectType) { - continue; - } - - return $this->processCallLike($node, $addClosureParamTypeFromObject, $type); - } - - return null; + throw new ShouldNotHappenException(sprintf( + '"%s" rule is deprecated as too specific and not practical for general core rules', + self::class + )); } /** @@ -108,80 +65,5 @@ public function refactor(Node $node): ?Node public function configure(array $configuration): void { Assert::allIsAOf($configuration, AddClosureParamTypeFromObject::class); - - $this->addClosureParamTypeFromObjects = $configuration; - } - - private function processCallLike( - MethodCall|StaticCall $callLike, - AddClosureParamTypeFromObject $addClosureParamTypeFromArg, - ObjectType $objectType - ): MethodCall|StaticCall|null { - if ($callLike->isFirstClassCallable()) { - return null; - } - - $callLikeArg = $callLike->args[$addClosureParamTypeFromArg->getCallLikePosition()] ?? null; - if (! $callLikeArg instanceof Arg) { - return null; - } - - // int positions shouldn't have names - if ($callLikeArg->name instanceof Identifier) { - return null; - } - - $functionLike = $callLikeArg->value; - if (! $functionLike instanceof Closure && ! $functionLike instanceof ArrowFunction) { - return null; - } - - if (! isset($functionLike->params[$addClosureParamTypeFromArg->getFunctionLikePosition()])) { - return null; - } - - $callLikeArg = $callLike->getArgs()[self::DEFAULT_CLOSURE_ARG_POSITION] ?? null; - if (! $callLikeArg instanceof Arg) { - return null; - } - - $hasChanged = $this->refactorParameter( - $functionLike->params[$addClosureParamTypeFromArg->getFunctionLikePosition()], - $objectType, - ); - - if ($hasChanged) { - return $callLike; - } - - return null; - } - - private function refactorParameter(Param $param, ObjectType $objectType): bool - { - // already set → no change - if ($param->type instanceof Node) { - $currentParamType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($param->type); - if ($this->typeComparator->areTypesEqual($currentParamType, $objectType)) { - return false; - } - } - - $paramTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($objectType, TypeKind::PARAM); - $param->type = $paramTypeNode; - - return true; - } - - private function isCallMatch( - Name|Expr $name, - AddClosureParamTypeFromObject $addClosureParamTypeFromArg, - StaticCall|MethodCall $call - ): bool { - if (! $this->isObjectType($name, $addClosureParamTypeFromArg->getObjectType())) { - return false; - } - - return $this->isName($call->name, $addClosureParamTypeFromArg->getMethodName()); } } diff --git a/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector.php b/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector.php index 339b57e2db1..7247b727a02 100644 --- a/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector.php +++ b/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector.php @@ -5,46 +5,24 @@ namespace Rector\TypeDeclaration\Rector\FunctionLike; use PhpParser\Node; -use PhpParser\Node\Arg; use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; -use PhpParser\Node\FunctionLike; -use PhpParser\Node\Identifier; -use PhpParser\Node\Param; -use PHPStan\Type\MixedType; use PHPStan\Type\StringType; +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; use Rector\Contract\Rector\ConfigurableRectorInterface; -use Rector\NodeTypeResolver\TypeComparator\TypeComparator; -use Rector\Php\PhpVersionProvider; -use Rector\PHPStanStaticTypeMapper\Enum\TypeKind; +use Rector\Exception\ShouldNotHappenException; use Rector\Rector\AbstractRector; -use Rector\StaticTypeMapper\StaticTypeMapper; use Rector\TypeDeclaration\ValueObject\AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration; -use Rector\ValueObject\PhpVersionFeature; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; use Webmozart\Assert\Assert; /** - * @see \Rector\Tests\TypeDeclaration\Rector\FunctionLike\AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector\AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRectorTest + * @deprecated as too specific and not useful in Rector core. Implement it locally instead if needed. */ -final class AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector extends AbstractRector implements ConfigurableRectorInterface +final class AddParamTypeForFunctionLikeWithinCallLikeArgDeclarationRector extends AbstractRector implements ConfigurableRectorInterface, DeprecatedInterface { - /** - * @var AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration[] - */ - private array $addParamTypeForFunctionLikeParamDeclarations = []; - - private bool $hasChanged = false; - - public function __construct( - private readonly TypeComparator $typeComparator, - private readonly PhpVersionProvider $phpVersionProvider, - private readonly StaticTypeMapper $staticTypeMapper, - ) { - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Add param types where needed', [ @@ -83,38 +61,10 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - $this->hasChanged = false; - foreach ($this->addParamTypeForFunctionLikeParamDeclarations as $addParamTypeForFunctionLikeParamDeclaration) { - $type = match (true) { - $node instanceof MethodCall => $node->var, - $node instanceof StaticCall => $node->class, - default => null, - }; - - if (! $type instanceof Node) { - continue; - } - - if (! $this->isObjectType($type, $addParamTypeForFunctionLikeParamDeclaration->getObjectType())) { - continue; - } - - if (! ($node->name ?? null) instanceof Identifier) { - continue; - } - - if (! $this->isName($node->name, $addParamTypeForFunctionLikeParamDeclaration->getMethodName())) { - continue; - } - - $this->processFunctionLike($node, $addParamTypeForFunctionLikeParamDeclaration); - } - - if (! $this->hasChanged) { - return null; - } - - return $node; + throw new ShouldNotHappenException(sprintf( + '"%s" rule is deprecated as too specific and not practical for general core rules', + self::class + )); } /** @@ -123,98 +73,5 @@ public function refactor(Node $node): ?Node public function configure(array $configuration): void { Assert::allIsAOf($configuration, AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration::class); - - $this->addParamTypeForFunctionLikeParamDeclarations = $configuration; - } - - private function processFunctionLike( - CallLike $callLike, - AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration $addParamTypeForFunctionLikeWithinCallLikeArgDeclaration - ): void { - if ($callLike->isFirstClassCallable()) { - return; - } - - if (is_int($addParamTypeForFunctionLikeWithinCallLikeArgDeclaration->getCallLikePosition())) { - if ($callLike->getArgs() === []) { - return; - } - - $arg = $callLike->args[$addParamTypeForFunctionLikeWithinCallLikeArgDeclaration->getCallLikePosition()] ?? null; - - if (! $arg instanceof Arg) { - return; - } - - // int positions shouldn't have names - if ($arg->name instanceof Identifier) { - return; - } - } else { - $args = array_filter($callLike->getArgs(), static function (Arg $arg) use ( - $addParamTypeForFunctionLikeWithinCallLikeArgDeclaration - ): bool { - if (! $arg->name instanceof Identifier) { - return false; - } - - return $arg->name->name === $addParamTypeForFunctionLikeWithinCallLikeArgDeclaration->getCallLikePosition(); - }); - - if ($args === []) { - return; - } - - $arg = array_values($args)[0]; - } - - $functionLike = $arg->value; - if (! $functionLike instanceof FunctionLike) { - return; - } - - if (! isset($functionLike->params[$addParamTypeForFunctionLikeWithinCallLikeArgDeclaration->getFunctionLikePosition()])) { - return; - } - - $this->refactorParameter( - $functionLike->params[$addParamTypeForFunctionLikeWithinCallLikeArgDeclaration->getFunctionLikePosition()], - $addParamTypeForFunctionLikeWithinCallLikeArgDeclaration, - ); - } - - private function refactorParameter( - Param $param, - AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration $addParamTypeForFunctionLikeWithinCallLikeArgDeclaration, - ): void { - $newParameterType = $addParamTypeForFunctionLikeWithinCallLikeArgDeclaration->getParamType(); - - // already set → no change - if ($param->type instanceof Node) { - $currentParamType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($param->type); - if ($this->typeComparator->areTypesEqual($currentParamType, $newParameterType)) { - return; - } - } - - $paramTypeNode = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode( - $newParameterType, - TypeKind::PARAM - ); - - $this->hasChanged = true; - - // remove it - if ($newParameterType instanceof MixedType) { - if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::MIXED_TYPE)) { - $param->type = $paramTypeNode; - return; - } - - $param->type = null; - return; - } - - $param->type = $paramTypeNode; } } diff --git a/rules/TypeDeclaration/ValueObject/AddClosureParamTypeFromArg.php b/rules/TypeDeclaration/ValueObject/AddClosureParamTypeFromArg.php index 780302b357c..c6cc494d0af 100644 --- a/rules/TypeDeclaration/ValueObject/AddClosureParamTypeFromArg.php +++ b/rules/TypeDeclaration/ValueObject/AddClosureParamTypeFromArg.php @@ -7,6 +7,9 @@ use PHPStan\Type\ObjectType; use Rector\Validation\RectorAssert; +/** + * @deprecated as related rule is deprecated + */ final readonly class AddClosureParamTypeFromArg { /** diff --git a/rules/TypeDeclaration/ValueObject/AddClosureParamTypeFromObject.php b/rules/TypeDeclaration/ValueObject/AddClosureParamTypeFromObject.php index 82cba439845..dd9ff18effc 100644 --- a/rules/TypeDeclaration/ValueObject/AddClosureParamTypeFromObject.php +++ b/rules/TypeDeclaration/ValueObject/AddClosureParamTypeFromObject.php @@ -7,6 +7,9 @@ use PHPStan\Type\ObjectType; use Rector\Validation\RectorAssert; +/** + * @deprecated as related rule is deprecated + */ final readonly class AddClosureParamTypeFromObject { /** diff --git a/rules/TypeDeclaration/ValueObject/AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration.php b/rules/TypeDeclaration/ValueObject/AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration.php index 69f99f35908..1b81730d991 100644 --- a/rules/TypeDeclaration/ValueObject/AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration.php +++ b/rules/TypeDeclaration/ValueObject/AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration.php @@ -9,7 +9,7 @@ use Rector\Validation\RectorAssert; /** - * @see \Rector\Tests\TypeDeclaration\Rector\FunctionLike\AddParamTypeForFunctionLikeWithinCallLikeDeclarationRector\AddParamTypeForFunctionLikeWithinCallLikeDeclarationRectorTest + * @deprecated as related rule is deprecated */ final readonly class AddParamTypeForFunctionLikeWithinCallLikeArgDeclaration { diff --git a/src/NodeTypeResolver/PHPStan/Type/StaticTypeAnalyzer.php b/src/NodeTypeResolver/PHPStan/Type/StaticTypeAnalyzer.php index 119716fb830..d988a153561 100644 --- a/src/NodeTypeResolver/PHPStan/Type/StaticTypeAnalyzer.php +++ b/src/NodeTypeResolver/PHPStan/Type/StaticTypeAnalyzer.php @@ -10,16 +10,11 @@ use PHPStan\Type\MixedType; use PHPStan\Type\ObjectType; use PHPStan\Type\Type; +use PHPStan\Type\TypeCombinator; use PHPStan\Type\UnionType; -use Rector\PHPStanStaticTypeMapper\TypeAnalyzer\UnionTypeAnalyzer; final readonly class StaticTypeAnalyzer { - public function __construct( - private UnionTypeAnalyzer $unionTypeAnalyzer - ) { - } - public function isAlwaysTruableType(Type $type): bool { if ($type instanceof MixedType) { @@ -34,7 +29,7 @@ public function isAlwaysTruableType(Type $type): bool return $this->isAlwaysTruableArrayType($type); } - if ($type instanceof UnionType && $this->unionTypeAnalyzer->isNullable($type)) { + if ($type instanceof UnionType && TypeCombinator::containsNull($type)) { return false; } diff --git a/src/PHPStanStaticTypeMapper/TypeAnalyzer/UnionTypeAnalyzer.php b/src/PHPStanStaticTypeMapper/TypeAnalyzer/UnionTypeAnalyzer.php deleted file mode 100644 index e1f2f4ca875..00000000000 --- a/src/PHPStanStaticTypeMapper/TypeAnalyzer/UnionTypeAnalyzer.php +++ /dev/null @@ -1,16 +0,0 @@ -