diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/AddParamStringTypeFromSprintfUseRectorTest.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/AddParamStringTypeFromSprintfUseRectorTest.php deleted file mode 100644 index ee0cfa78f73..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/AddParamStringTypeFromSprintfUseRectorTest.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/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/add_arrow_function.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/add_arrow_function.php.inc deleted file mode 100644 index 702d3b9509a..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/add_arrow_function.php.inc +++ /dev/null @@ -1,27 +0,0 @@ - sprintf('Hello %s', $name); - } -} - -?> ------ - sprintf('Hello %s', $name); - } -} - -?> diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/constant_variable.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/constant_variable.php.inc deleted file mode 100644 index ee917caad7f..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/constant_variable.php.inc +++ /dev/null @@ -1,29 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/cover_closure.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/cover_closure.php.inc deleted file mode 100644 index 0ef5f6bd900..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/cover_closure.php.inc +++ /dev/null @@ -1,33 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/other_function_and_sprintf.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/other_function_and_sprintf.php.inc deleted file mode 100644 index 44234c77c1a..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/other_function_and_sprintf.php.inc +++ /dev/null @@ -1,35 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/pass_sprintf.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/pass_sprintf.php.inc deleted file mode 100644 index 246b1e0dc56..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/pass_sprintf.php.inc +++ /dev/null @@ -1,27 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/skip_conditional_non_string.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/skip_conditional_non_string.php.inc deleted file mode 100644 index fdf88a20cd8..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/skip_conditional_non_string.php.inc +++ /dev/null @@ -1,20 +0,0 @@ - 'Fatal error', - \E_PARSE => 'Parse error', - \E_USER_WARNING, \E_WARNING, \E_COMPILE_WARNING => 'Warning', - \E_USER_NOTICE, \E_NOTICE => 'Notice', - \E_USER_DEPRECATED, \E_DEPRECATED => 'Deprecated', - default => sprintf('Unknown (%s)', $errno), - }; - } -} \ No newline at end of file diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/skip_with_empty_check.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/skip_with_empty_check.php.inc deleted file mode 100644 index 85d1f03673d..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector/Fixture/skip_with_empty_check.php.inc +++ /dev/null @@ -1,16 +0,0 @@ -rule(AddParamStringTypeFromSprintfUseRector::class); -}; diff --git a/rules/TypeDeclaration/NodeAnalyzer/VariableInSprintfMaskMatcher.php b/rules/TypeDeclaration/NodeAnalyzer/VariableInSprintfMaskMatcher.php deleted file mode 100644 index f23ae12ffac..00000000000 --- a/rules/TypeDeclaration/NodeAnalyzer/VariableInSprintfMaskMatcher.php +++ /dev/null @@ -1,106 +0,0 @@ -expr]; - } else { - $stmts = (array) $functionLike->stmts; - } - - $funcCalls = $this->betterNodeFinder->findInstancesOfScoped($stmts, FuncCall::class); - $funcCalls = array_values( - array_filter($funcCalls, fn (FuncCall $funcCall): bool => $this->nodeNameResolver->isName( - $funcCall->name, - 'sprintf' - )) - ); - - if (count($funcCalls) !== 1) { - return false; - } - - $funcCall = $funcCalls[0]; - - if ($funcCall->isFirstClassCallable()) { - return false; - } - - $args = $funcCall->getArgs(); - if (count($args) < 2) { - return false; - } - - /** @var Arg $messageArg */ - $messageArg = array_shift($args); - - $messageValue = $this->valueResolver->getValue($messageArg->value); - if (! is_string($messageValue)) { - return false; - } - - // match all %s, %d types by position - $masks = Strings::match($messageValue, '#%[sd]#'); - - foreach ($args as $position => $arg) { - if (! $arg->value instanceof Variable) { - continue; - } - - if (! $this->nodeNameResolver->isName($arg->value, $variableName)) { - continue; - } - - if (! isset($masks[$position])) { - continue; - } - - $knownMaskOnPosition = $masks[$position]; - if ($knownMaskOnPosition !== $mask) { - continue; - } - - $type = $this->nodeTypeResolver->getNativeType($arg->value); - if ($type instanceof MixedType && $type->getSubtractedType() instanceof UnionType) { - continue; - } - - return true; - } - - return false; - } -} diff --git a/rules/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector.php b/rules/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector.php index 11dda3779ab..0dc32d51d55 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/AddParamStringTypeFromSprintfUseRector.php @@ -5,32 +5,21 @@ namespace Rector\TypeDeclaration\Rector\ClassMethod; use PhpParser\Node; -use PhpParser\Node\Expr; use PhpParser\Node\Expr\ArrowFunction; use PhpParser\Node\Expr\Closure; -use PhpParser\Node\Identifier; -use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Function_; +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; +use Rector\Exception\ShouldNotHappenException; use Rector\Rector\AbstractRector; use Rector\RuleDoc\CodeSample\CodeSample; use Rector\RuleDoc\RuleDefinition; -use Rector\TypeDeclaration\Guard\ParamTypeAddGuard; -use Rector\TypeDeclaration\NodeAnalyzer\VariableInSprintfMaskMatcher; -use Rector\VendorLocker\ParentClassMethodTypeOverrideGuard; /** - * @see \Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddParamStringTypeFromSprintfUseRector\AddParamStringTypeFromSprintfUseRectorTest + * @deprecated This rule is deprecated, as sprintf masks do not guarantee a string parameter - int/float arguments are silently converted, so forcing a string type can add an invalid type. */ -final class AddParamStringTypeFromSprintfUseRector extends AbstractRector +final class AddParamStringTypeFromSprintfUseRector extends AbstractRector implements DeprecatedInterface { - public function __construct( - private readonly VariableInSprintfMaskMatcher $variableInSprintfMaskMatcher, - private readonly ParentClassMethodTypeOverrideGuard $parentClassMethodTypeOverrideGuard, - private readonly ParamTypeAddGuard $paramTypeAddGuard - ) { - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( @@ -71,48 +60,11 @@ public function getNodeTypes(): array /** * @param ClassMethod|Function_|Closure|ArrowFunction $node */ - public function refactor(Node $node): ClassMethod|Function_|Closure|ArrowFunction|null + public function refactor(Node $node): ?Node { - if ($node instanceof ClassMethod && $node->stmts === null) { - return null; - } - - if ($node->getParams() === []) { - return null; - } - - if ($node instanceof ClassMethod && $this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($node)) { - return null; - } - - $hasChanged = false; - foreach ($node->getParams() as $param) { - if ($param->type instanceof Node) { - continue; - } - - // skip non string default value - if ($param->default instanceof Expr && ! $param->default instanceof String_) { - continue; - } - - if (! $this->paramTypeAddGuard->isLegal($param, $node)) { - continue; - } - - $variableName = $this->getName($param); - if (! $this->variableInSprintfMaskMatcher->matchMask($node, $variableName, '%s')) { - continue; - } - - $param->type = new Identifier('string'); - $hasChanged = true; - } - - if (! $hasChanged) { - return null; - } - - return $node; + throw new ShouldNotHappenException(sprintf( + '"%s" rule is deprecated, as sprintf masks convert int/float arguments to string and would add an invalid param type', + self::class + )); } } diff --git a/src/Config/Level/TypeDeclarationLevel.php b/src/Config/Level/TypeDeclarationLevel.php index f9dc1e8da86..5bcf947ec89 100644 --- a/src/Config/Level/TypeDeclarationLevel.php +++ b/src/Config/Level/TypeDeclarationLevel.php @@ -23,7 +23,6 @@ use Rector\TypeDeclaration\Rector\Class_\TypedStaticPropertyInBehatContextRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddMethodCallBasedStrictParamTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddParamFromDimFetchKeyUseRector; -use Rector\TypeDeclaration\Rector\ClassMethod\AddParamStringTypeFromSprintfUseRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeBasedOnPHPUnitDataProviderRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeFromPropertyTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationBasedOnParentClassMethodRector; @@ -175,7 +174,6 @@ final class TypeDeclarationLevel AddClosureParamTypeFromVariableCallRector::class, StrictArrayParamDimFetchRector::class, AddParamFromDimFetchKeyUseRector::class, - AddParamStringTypeFromSprintfUseRector::class, // possibly based on docblocks, but also helpful, intentionally last AddArrayFunctionClosureParamTypeRector::class,