diff --git a/phpstan.neon b/phpstan.neon index 7417f795c96..cf5840b5707 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -417,6 +417,7 @@ parameters: - '#Register "Rector\\Php81\\Rector\\ClassMethod\\NewInInitializerRector" service to "php81\.php" config set#' - '#Class "Rector\\CodingStyle\\Rector\\String_\\SymplifyQuoteEscapeRector" is missing @see annotation with test case class reference#' - '#Class "Rector\\Php81\\Rector\\ClassMethod\\NewInInitializerRector" is missing @see annotation with test case class reference#' + - '#Class "Rector\\TypeDeclaration\\Rector\\ClassMethod\\StrictStringParamConcatRector" is missing @see annotation with test case class reference#' # false positive - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/do_not_change_different_type_default_value.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/do_not_change_different_type_default_value.php.inc deleted file mode 100644 index 413ffc1bd40..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/do_not_change_different_type_default_value.php.inc +++ /dev/null @@ -1,35 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/nullable_param_from_null_compare.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/nullable_param_from_null_compare.php.inc deleted file mode 100644 index e625cb0ea0c..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/nullable_param_from_null_compare.php.inc +++ /dev/null @@ -1,35 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/skip_another_type.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/skip_another_type.php.inc deleted file mode 100644 index 1f17a905643..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/skip_another_type.php.inc +++ /dev/null @@ -1,11 +0,0 @@ -= 1_073_741_824) { - $bytes = number_format($bytes / 1_073_741_824, 1).' GB'; - } elseif ($bytes >= 1_048_576) { - $bytes = number_format($bytes / 1_048_576, 1).' MB'; - } elseif ($bytes >= 1024) { - $bytes = number_format($bytes / 1024, 1).' KB'; - } elseif ($bytes > 1) { - $bytes .= ' bytes'; - } elseif (1 === $bytes) { - $bytes .= ' byte'; - } else { - $bytes = '0 bytes'; - } - - return $bytes; - } -} diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/skip_override_trait.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/skip_override_trait.php.inc deleted file mode 100644 index 681bd56f3b0..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/skip_override_trait.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/with_inner_closure.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/with_inner_closure.php.inc deleted file mode 100644 index 6e15c876672..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/with_inner_closure.php.inc +++ /dev/null @@ -1,39 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/with_inner_function.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/with_inner_function.php.inc deleted file mode 100644 index 202d01ed284..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Fixture/with_inner_function.php.inc +++ /dev/null @@ -1,37 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Source/SomeTrait.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Source/SomeTrait.php deleted file mode 100644 index 639893260f6..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/Source/SomeTrait.php +++ /dev/null @@ -1,10 +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/ClassMethod/StrictStringParamConcatRector/config/configured_rule.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/config/configured_rule.php deleted file mode 100644 index 27e602c5f8b..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector/config/configured_rule.php +++ /dev/null @@ -1,9 +0,0 @@ -withRules([StrictStringParamConcatRector::class]); diff --git a/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php b/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php index 1f09f021414..9c4f1b3338e 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/StrictStringParamConcatRector.php @@ -5,41 +5,22 @@ namespace Rector\TypeDeclaration\Rector\ClassMethod; use PhpParser\Node; -use PhpParser\Node\Expr; -use PhpParser\Node\Expr\Assign; -use PhpParser\Node\Expr\AssignOp\Concat; use PhpParser\Node\Expr\Closure; -use PhpParser\Node\Expr\Variable; -use PhpParser\Node\FunctionLike; -use PhpParser\Node\Identifier; -use PhpParser\Node\NullableType; -use PhpParser\Node\Param; -use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Function_; -use PhpParser\NodeVisitor; -use PHPStan\Type\MixedType; -use PHPStan\Type\Type; -use PHPStan\Type\TypeCombinator; -use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; +use Rector\Exception\ShouldNotHappenException; use Rector\Rector\AbstractRector; use Rector\ValueObject\PhpVersionFeature; -use Rector\VendorLocker\ParentClassMethodTypeOverrideGuard; use Rector\VersionBonding\Contract\MinPhpVersionInterface; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** - * @see \Rector\Tests\TypeDeclaration\Rector\ClassMethod\StrictStringParamConcatRector\StrictStringParamConcatRectorTest + * @deprecated This rule is deprecated as it produces too many false positives. */ -final class StrictStringParamConcatRector extends AbstractRector implements MinPhpVersionInterface +final class StrictStringParamConcatRector extends AbstractRector implements MinPhpVersionInterface, DeprecatedInterface { - public function __construct( - private readonly ParentClassMethodTypeOverrideGuard $parentClassMethodTypeOverrideGuard, - private readonly PhpDocInfoFactory $phpDocInfoFactory, - ) { - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Add string type based on concat use', [ @@ -85,139 +66,9 @@ public function provideMinPhpVersion(): int */ public function refactor(Node $node): ?Node { - if ($node instanceof ClassMethod && $this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node)) { - return null; - } - - $hasChanged = false; - $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); - - foreach ($node->getParams() as $param) { - if ($param->type instanceof Node) { - continue; - } - - $variableConcattedFromParam = $this->resolveVariableConcattedFromParam($param, $node); - if (! $variableConcattedFromParam instanceof Variable) { - continue; - } - - $paramDocType = $phpDocInfo->getParamType($this->getName($param)); - if (! $paramDocType instanceof MixedType && ! $paramDocType->isString()->yes()) { - continue; - } - - $nativeType = $this->nodeTypeResolver->getNativeType($variableConcattedFromParam); - if (! $nativeType instanceof MixedType) { - continue; - } - - $subtractedType = $nativeType->getSubtractedType(); - if (! $subtractedType instanceof Type) { - $param->type = new Identifier('string'); - $hasChanged = true; - - continue; - } - - if (TypeCombinator::containsNull($subtractedType)) { - $param->type = new NullableType(new Identifier('string')); - $hasChanged = true; - } - } - - if ($hasChanged) { - return $node; - } - - return null; - } - - private function resolveVariableConcattedFromParam( - Param $param, - ClassMethod|Function_|Closure $functionLike - ): ?Variable { - if ($functionLike->stmts === null) { - return null; - } - - if ($param->default instanceof Expr && ! $this->getType($param->default)->isString()->yes()) { - return null; - } - - $paramName = $this->getName($param); - $variableConcatted = null; - - $this->traverseNodesWithCallable($functionLike->stmts, function (Node $node) use ( - $paramName, - &$variableConcatted, - ): int|null { - // skip nested class and function nodes - if ($node instanceof FunctionLike || $node instanceof Class_) { - return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN; - } - - if ($node instanceof Assign && $node->var instanceof Variable && $this->isName($node->var, $paramName)) { - $variableConcatted = null; - return NodeVisitor::STOP_TRAVERSAL; - } - - $expr = $this->resolveAssignConcatVariable($node, $paramName); - if ($expr instanceof Variable) { - $variableConcatted = $expr; - } - - $variableBinaryConcat = $this->resolveBinaryConcatVariable($node, $paramName); - if ($variableBinaryConcat instanceof Variable) { - $variableConcatted = $variableBinaryConcat; - } - - return null; - }); - - return $variableConcatted; - } - - private function isVariableWithSameParam(Expr $expr, string $paramName): bool - { - if (! $expr instanceof Variable) { - return false; - } - - return $this->isName($expr, $paramName); - } - - private function resolveAssignConcatVariable(Node $node, string $paramName): ?Expr - { - if (! $node instanceof Concat) { - return null; - } - - if ($this->isVariableWithSameParam($node->var, $paramName)) { - return $node->var; - } - - if ($this->isVariableWithSameParam($node->expr, $paramName)) { - return $node->expr; - } - - return null; - } - - private function resolveBinaryConcatVariable(Node $node, string $paramName): ?Expr - { - if (! $node instanceof Expr\BinaryOp\Concat) { - return null; - } - - if ($this->isVariableWithSameParam($node->left, $paramName)) { - return $node->left; - } - - if ($this->isVariableWithSameParam($node->right, $paramName)) { - return $node->right; - } - - return null; + throw new ShouldNotHappenException(sprintf( + '"%s" is deprecated as it produces too many false positives. Add the type manually where needed instead', + self::class + )); } } diff --git a/src/Config/Level/TypeDeclarationLevel.php b/src/Config/Level/TypeDeclarationLevel.php index 5923e119d4d..5d22033731f 100644 --- a/src/Config/Level/TypeDeclarationLevel.php +++ b/src/Config/Level/TypeDeclarationLevel.php @@ -50,7 +50,6 @@ use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromSymfonySerializerRector; use Rector\TypeDeclaration\Rector\ClassMethod\ReturnUnionTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\StrictArrayParamDimFetchRector; -use Rector\TypeDeclaration\Rector\ClassMethod\StrictStringParamConcatRector; use Rector\TypeDeclaration\Rector\ClassMethod\StringReturnTypeFromStrictScalarReturnsRector; use Rector\TypeDeclaration\Rector\ClassMethod\StringReturnTypeFromStrictStringReturnsRector; use Rector\TypeDeclaration\Rector\Closure\AddClosureNeverReturnTypeRector; @@ -157,7 +156,6 @@ final class TypeDeclarationLevel AddReturnTypeDeclarationBasedOnParentClassMethodRector::class, ReturnTypeFromStrictFluentReturnRector::class, ReturnNeverTypeRector::class, - StrictStringParamConcatRector::class, // jms attributes ObjectTypedPropertyFromJMSSerializerAttributeTypeRector::class,