diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/case_insensitive_function_name.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/case_insensitive_function_name.php.inc deleted file mode 100644 index 51e3661d8b9..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/case_insensitive_function_name.php.inc +++ /dev/null @@ -1,27 +0,0 @@ - ------ - diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/crypt_one_arg.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/crypt_one_arg.php.inc deleted file mode 100644 index 84bc987c53c..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/crypt_one_arg.php.inc +++ /dev/null @@ -1,37 +0,0 @@ - ------ - diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/explicit_mixed_in_trait.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/explicit_mixed_in_trait.php.inc deleted file mode 100644 index 6817eee40a7..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/explicit_mixed_in_trait.php.inc +++ /dev/null @@ -1,29 +0,0 @@ -title = $title; - return trim($this->title); - } -} - -?> ------ -title = $title; - return trim((string) $this->title); - } -} - -?> diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/named_argument.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/named_argument.php.inc deleted file mode 100644 index ff15e03be88..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/named_argument.php.inc +++ /dev/null @@ -1,27 +0,0 @@ - ------ - diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/non_string_param_type.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/non_string_param_type.php.inc deleted file mode 100644 index c992daa9e76..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/non_string_param_type.php.inc +++ /dev/null @@ -1,27 +0,0 @@ - ------ - diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/non_string_param_type_in_use_closure.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/non_string_param_type_in_use_closure.php.inc deleted file mode 100644 index 23c7a9c89cb..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/non_string_param_type_in_use_closure.php.inc +++ /dev/null @@ -1,31 +0,0 @@ - ------ - diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/normal_variable_in_trait.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/normal_variable_in_trait.php.inc deleted file mode 100644 index ba5719c1455..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/normal_variable_in_trait.php.inc +++ /dev/null @@ -1,27 +0,0 @@ - ------ - diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/null_defined_in_variable_first.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/null_defined_in_variable_first.php.inc index cbf966b378a..2597be09bd9 100644 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/null_defined_in_variable_first.php.inc +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/null_defined_in_variable_first.php.inc @@ -22,7 +22,7 @@ class NullDefinedInVariableFirst public function getTitle() { $title = null; - return trim((string) $title); + return trim(''); } } diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_case_insensitive_function_name.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_case_insensitive_function_name.php.inc new file mode 100644 index 00000000000..a19fee058c2 --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_case_insensitive_function_name.php.inc @@ -0,0 +1,13 @@ + diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_crypt_one_arg.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_crypt_one_arg.php.inc new file mode 100644 index 00000000000..eb32390104c --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_crypt_one_arg.php.inc @@ -0,0 +1,18 @@ + diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_explicit_mixed_in_trait.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_explicit_mixed_in_trait.php.inc new file mode 100644 index 00000000000..fa829d4b1e7 --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_explicit_mixed_in_trait.php.inc @@ -0,0 +1,14 @@ +title = $title; + return trim($this->title); + } +} + +?> diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_named_argument.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_named_argument.php.inc new file mode 100644 index 00000000000..d6367c3ec0b --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_named_argument.php.inc @@ -0,0 +1,13 @@ + diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_non_string_param_type.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_non_string_param_type.php.inc new file mode 100644 index 00000000000..3a189014a3b --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_non_string_param_type.php.inc @@ -0,0 +1,13 @@ + diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_non_string_param_type_in_use_closure.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_non_string_param_type_in_use_closure.php.inc new file mode 100644 index 00000000000..a6f62922cdf --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_non_string_param_type_in_use_closure.php.inc @@ -0,0 +1,15 @@ + diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_normal_variable_in_trait.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_normal_variable_in_trait.php.inc new file mode 100644 index 00000000000..5eed2087d5f --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_normal_variable_in_trait.php.inc @@ -0,0 +1,13 @@ + diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_ternary_with_ints.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_ternary_with_ints.php.inc new file mode 100644 index 00000000000..926c0eba490 --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_ternary_with_ints.php.inc @@ -0,0 +1,18 @@ + diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_with_existing_cast_on_ternary.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_with_existing_cast_on_ternary.php.inc new file mode 100644 index 00000000000..d5a478b92b2 --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_with_existing_cast_on_ternary.php.inc @@ -0,0 +1,25 @@ +Get('account_code') ?: $this->Get('customer_id')); + } + + public function run2() + { + return $relpath + . '/' . rawurlencode((string) $this->Get('account_code') ?: null); + } + + public function Get($fieldname) + { + return $this->{$fieldname} ?? null; + } +} + +?> diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_with_nullable_docblock.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_with_nullable_docblock.php.inc new file mode 100644 index 00000000000..1a70c2d84b1 --- /dev/null +++ b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/skip_with_nullable_docblock.php.inc @@ -0,0 +1,22 @@ +importedId) > 0) { + $this->importedId = $importedId; + } + } +} + +?> diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/ternary_with_ints.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/ternary_with_ints.php.inc deleted file mode 100644 index fa9ae6738ce..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/ternary_with_ints.php.inc +++ /dev/null @@ -1,37 +0,0 @@ - ------ - diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/with_existing_cast_on_ternary.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/with_existing_cast_on_ternary.php.inc deleted file mode 100644 index 5c589a3ad5c..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/with_existing_cast_on_ternary.php.inc +++ /dev/null @@ -1,51 +0,0 @@ -Get('account_code') ?: $this->Get('customer_id')); - } - - public function run2() - { - return $relpath - . '/' . rawurlencode((string) $this->Get('account_code') ?: null); - } - - public function Get($fieldname) - { - return $this->{$fieldname} ?? null; - } -} - -?> ------ -Get('account_code') ?: (string) $this->Get('customer_id')); - } - - public function run2() - { - return $relpath - . '/' . rawurlencode((string) $this->Get('account_code') ?: ''); - } - - public function Get($fieldname) - { - return $this->{$fieldname} ?? null; - } -} - -?> diff --git a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/with_nullable_docblock.php.inc b/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/with_nullable_docblock.php.inc deleted file mode 100644 index b48bc1f704a..00000000000 --- a/rules-tests/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector/Fixture/with_nullable_docblock.php.inc +++ /dev/null @@ -1,45 +0,0 @@ -importedId) > 0) { - $this->importedId = $importedId; - } - } -} - -?> ------ -importedId) > 0) { - $this->importedId = $importedId; - } - } -} - -?> diff --git a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null.php.inc b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null.php.inc index a67a072f816..7bd25ed288d 100644 --- a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null.php.inc +++ b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null.php.inc @@ -2,7 +2,15 @@ namespace Rector\Tests\Php85\Rector\FuncCall\ArrayKeyExistsNullToEmptyStringRector\Fixture; -array_key_exists(null, $array); +final class KeyNull +{ + public function run($array) + { + array_key_exists(null, $array); + + array_key_exists(array: $array, key: null); + } +} ?> ----- @@ -10,6 +18,14 @@ array_key_exists(null, $array); namespace Rector\Tests\Php85\Rector\FuncCall\ArrayKeyExistsNullToEmptyStringRector\Fixture; -array_key_exists('', $array); +final class KeyNull +{ + public function run($array) + { + array_key_exists('', $array); + + array_key_exists(array: $array, key: ''); + } +} -?> \ No newline at end of file +?> diff --git a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null_named_flip.php.inc b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null_named_flip.php.inc deleted file mode 100644 index b8606d38af2..00000000000 --- a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null_named_flip.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - ------ - \ No newline at end of file diff --git a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null_var.php.inc b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null_var.php.inc deleted file mode 100644 index dde06a0d90c..00000000000 --- a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/key_null_var.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - ------ - \ No newline at end of file diff --git a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_integer_key.php.inc b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_integer_key.php.inc index 8718ea6efd8..dda67a052b2 100644 --- a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_integer_key.php.inc +++ b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_integer_key.php.inc @@ -2,4 +2,10 @@ namespace Rector\Tests\Php85\Rector\FuncCall\ArrayKeyExistsNullToEmptyStringRector\Fixture; -array_key_exists(0, $array); +final class SkipIntegerKey +{ + public function run($array) + { + array_key_exists(0, $array); + } +} diff --git a/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_mixed.php.inc b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_mixed.php.inc new file mode 100644 index 00000000000..f8fa1250b18 --- /dev/null +++ b/rules-tests/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector/Fixture/skip_mixed.php.inc @@ -0,0 +1,11 @@ +value; - - if ($this->valueResolver->isNull($argValue)) { - $args[$position]->value = $targetType === 'string' ? new String_('') : new Int_(0); - $funcCall->args = $args; - return $funcCall; - } - - // skip (string) ternary conditions with both values - if ($this->isStringCastedTernaryOfMixedTypes($argValue, $scope)) { - return null; - } - - if ($this->shouldSkipValue($argValue, $scope, $isTrait, $targetType)) { - return null; - } - - $parameterReflection = $parametersAcceptor->getParameters()[$position] ?? null; - if ($parameterReflection instanceof ExtendedNativeParameterReflection && $parameterReflection->getType() instanceof UnionType) { - $parameterType = $parameterReflection->getType(); - if (! $this->isValidUnionType($parameterType)) { - return null; - } - } - - if ($argValue instanceof Ternary && ! $this->shouldSkipValue($argValue->else, $scope, $isTrait, $targetType)) { - - if ($this->valueResolver->isNull($argValue->else)) { - $argValue->else = $targetType === 'string' ? new String_('') : new Int_(0); - } else { - $argValue->else = $targetType === 'string' ? new CastString_($argValue->else) : new CastInt_( - $argValue->else - ); - } - - $args[$position]->value = $argValue; - - return $funcCall; - } - - // already cast to the target type on a previous run, re-casting would nest a redundant cast - if ($this->isAlreadyCastToTargetType($argValue, $targetType)) { - return null; - } - - $wrapInParentheses = false; - if ($argValue instanceof Ternary && $argValue->cond instanceof CastString_) { - $wrapInParentheses = true; - } - - if ($targetType === 'string') { - $castedType = new CastString_($argValue); - } else { - $castedType = new CastInt_($argValue); - } - - if ($wrapInParentheses) { - $argValue->setAttribute(AttributeKey::WRAPPED_IN_PARENTHESES, true); - } - - $args[$position]->value = $castedType; - - return $funcCall; - } - - /** - * Structural check (immune to stale resolved types on re-printed nodes): the value is already a - * cast/literal of the target type, or a ternary whose both branches are. - */ - private function isAlreadyCastToTargetType(Expr $expr, string $targetType): bool - { - if ($expr instanceof Ternary) { - // short ternary "A ?: B" keeps the left value in cond; full ternary uses if - $left = $expr->if ?? $expr->cond; - return $this->isAlreadyCastToTargetType($left, $targetType) - && $this->isAlreadyCastToTargetType($expr->else, $targetType); - } - - if ($targetType === 'string') { - return $expr instanceof CastString_ || $expr instanceof String_ || $expr instanceof InterpolatedString; - } - - return $expr instanceof CastInt_ || $expr instanceof Int_; - } - - private function shouldSkipValue(Expr $expr, Scope $scope, bool $isTrait, string $targetType): bool - { - // array dim fetch value is mixed, null is not known - skip to avoid wrong (string) cast - if ($expr instanceof ArrayDimFetch) { - return true; - } - - if ($this->isPropertyFetchOnClassWithMagicGet($expr)) { - return true; - } - - $type = $this->nodeTypeResolver->getType($expr); - if ($type->isString()->yes() && $targetType === 'string') { - return true; - } - - if ($type->isInteger()->yes() && $targetType === 'int') { - return true; - } - - $nativeType = $this->nodeTypeResolver->getNativeType($expr); - if ($nativeType->isString()->yes() && $targetType === 'string') { - return true; - } - - if ($nativeType->isInteger()->yes() && $targetType === 'int') { - return true; - } - - if ($this->isPossibleArrayVariableName($type, $nativeType, $expr)) { - return true; - } - - if ($this->shouldSkipType($type)) { - return true; - } - - if ($expr instanceof InterpolatedString) { - return true; - } - - if ($this->isAnErrorType($expr, $nativeType, $scope)) { - return true; - } - - return $this->shouldSkipTrait($expr, $type, $isTrait); - } - - private function isPropertyFetchOnClassWithMagicGet(Expr $expr): bool - { - if (! $expr instanceof PropertyFetch) { - return false; - } - - $varType = $this->nodeTypeResolver->getType($expr->var); - if (! $varType instanceof ObjectType) { - return false; - } - - if (! $this->reflectionProvider->hasClass($varType->getClassName())) { - return false; - } - - return $this->reflectionProvider->getClass($varType->getClassName()) - ->hasMethod('__get'); - } - - private function isValidUnionType(Type $type): bool - { - if (! $type instanceof UnionType) { - return false; - } - - foreach ($type->getTypes() as $childType) { - if ($childType->isString()->yes()) { - continue; - } - - if ($childType->isInteger()->yes()) { - continue; - } - - if ($childType->isNull()->yes()) { - continue; - } - - return false; - } - - return true; - } - - private function shouldSkipType(Type $type): bool - { - return ! $type instanceof MixedType - && ! $type->isNull() - ->yes() - && ! $this->isValidUnionType($type); - } - - private function shouldSkipTrait(Expr $expr, Type $type, bool $isTrait): bool - { - if (! $type instanceof MixedType) { - return false; - } - - if (! $isTrait) { - return false; - } - - if ($type->isExplicitMixed()) { - return false; - } - - if (! $expr instanceof MethodCall) { - return $this->propertyFetchAnalyzer->isLocalPropertyFetch($expr); - } - - return true; - } - - private function isAnErrorType(Expr $expr, Type $type, Scope $scope): bool - { - if ($type instanceof ErrorType) { - return true; - } - - $parentScope = $scope->getParentScope(); - if ($parentScope instanceof Scope) { - return $parentScope->getType($expr) instanceof ErrorType; - } - - return $type instanceof MixedType - && ! $type->isExplicitMixed() - && $type->getSubtractedType() instanceof NullType; - } - - /** - * @see https://github.com/rectorphp/rector/issues/9447 for context - */ - private function isPossibleArrayVariableName(Type $passedType, Type $reflectionParamType, Expr $expr): bool - { - // could mixed, resp. array, no need to (string) cast array - if (! $passedType instanceof MixedType) { - return false; - } - - if (! $reflectionParamType->isArray()->maybe()) { - return false; - } - - if ($expr instanceof Variable && is_string($expr->name)) { - $variableName = $expr->name; - // most likely plural variable - return strlen($variableName) > 3 && str_ends_with($variableName, 's'); - } - - return false; - } - - private function isStringCastedTernaryOfMixedTypes(Expr $expr, Scope $scope): bool - { - if (! $expr instanceof Ternary) { - return false; - } - - if (! $expr->cond instanceof CastString_) { - return false; - } - - if (! $expr->if instanceof Expr) { - return false; - } - - $ifType = $scope->getType($expr->if); - $elseType = $scope->getType($expr->else); - return $ifType instanceof MixedType || $elseType instanceof MixedType; - } -} diff --git a/rules/Php81/Rector/FuncCall/NullToStrictIntPregSlitFuncCallLimitArgRector.php b/rules/Php81/Rector/FuncCall/NullToStrictIntPregSlitFuncCallLimitArgRector.php index 5a7acb3f72e..9167ffa1a3c 100644 --- a/rules/Php81/Rector/FuncCall/NullToStrictIntPregSlitFuncCallLimitArgRector.php +++ b/rules/Php81/Rector/FuncCall/NullToStrictIntPregSlitFuncCallLimitArgRector.php @@ -6,15 +6,9 @@ use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; -use PHPStan\Analyser\Scope; -use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\FunctionReflection; +use PhpParser\Node\Scalar\Int_; use Rector\NodeAnalyzer\ArgsAnalyzer; -use Rector\NodeTypeResolver\Node\AttributeKey; -use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; -use Rector\Php81\NodeManipulator\NullToStrictStringIntConverter; use Rector\Rector\AbstractRector; -use Rector\Reflection\ReflectionResolver; use Rector\RuleDoc\CodeSample\CodeSample; use Rector\RuleDoc\RuleDefinition; use Rector\ValueObject\PhpVersionFeature; @@ -27,9 +21,7 @@ final class NullToStrictIntPregSlitFuncCallLimitArgRector extends AbstractRector implements MinPhpVersionInterface { public function __construct( - private readonly ReflectionResolver $reflectionResolver, - private readonly ArgsAnalyzer $argsAnalyzer, - private readonly NullToStrictStringIntConverter $nullToStrictStringIntConverter + private readonly ArgsAnalyzer $argsAnalyzer ) { } @@ -87,35 +79,14 @@ public function refactor(Node $node): ?Node return null; } - $scope = $node->getAttribute(AttributeKey::SCOPE); - if (! $scope instanceof Scope) { + $activeArg = $args[$position]; + if (! $this->getType($activeArg->value)->isNull()->yes()) { return null; } - $classReflection = $scope->getClassReflection(); - $isTrait = $classReflection instanceof ClassReflection && $classReflection->isTrait(); + $activeArg->value = new Int_(0); - $functionReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node); - if (! $functionReflection instanceof FunctionReflection) { - return null; - } - - $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); - $result = $this->nullToStrictStringIntConverter->convertIfNull( - $node, - $args, - $position, - $isTrait, - $scope, - $parametersAcceptor, - 'int' - ); - - if ($result instanceof Node) { - return $result; - } - - return null; + return $node; } public function provideMinPhpVersion(): int diff --git a/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php b/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php index ea335386932..49889aae547 100644 --- a/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php +++ b/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php @@ -8,14 +8,12 @@ use PhpParser\Node\Arg; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Identifier; +use PhpParser\Node\Scalar\String_; use PHPStan\Analyser\Scope; -use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\FunctionReflection; use PHPStan\Reflection\Native\NativeFunctionReflection; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; use Rector\Php81\Enum\NameNullToStrictNullFunctionMap; -use Rector\Php81\NodeManipulator\NullToStrictStringIntConverter; use Rector\Rector\AbstractRector; use Rector\Reflection\ReflectionResolver; use Rector\RuleDoc\CodeSample\CodeSample; @@ -29,8 +27,7 @@ final class NullToStrictStringFuncCallArgRector extends AbstractRector implements MinPhpVersionInterface { public function __construct( - private readonly ReflectionResolver $reflectionResolver, - private readonly NullToStrictStringIntConverter $nullToStrictStringIntConverter + private readonly ReflectionResolver $reflectionResolver ) { } @@ -93,30 +90,20 @@ public function refactor(Node $node): ?Node return null; } - $classReflection = $scope->getClassReflection(); - $isTrait = $classReflection instanceof ClassReflection && $classReflection->isTrait(); - - $functionReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node); - if (! $functionReflection instanceof FunctionReflection) { - return null; - } - - $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); $isChanged = false; foreach ($positions as $position) { - $result = $this->nullToStrictStringIntConverter->convertIfNull( - $node, - $args, - (int) $position, - $isTrait, - $scope, - $parametersAcceptor - ); - if ($result instanceof Node) { - $node = $result; - $isChanged = true; + if (! isset($args[$position])) { + continue; } + + $activeArg = $args[$position]; + if (! $this->getType($activeArg->value)->isNull()->yes()) { + continue; + } + + $activeArg->value = new String_(''); + $isChanged = true; } if ($isChanged) { diff --git a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php index 105472c1325..2002019f74b 100644 --- a/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php +++ b/rules/Php85/Rector/FuncCall/ArrayKeyExistsNullToEmptyStringRector.php @@ -6,17 +6,9 @@ use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; -use PHPStan\Analyser\Scope; -use PHPStan\Reflection\ClassReflection; -use PHPStan\Reflection\FunctionReflection; -use PHPStan\Type\TypeCombinator; -use PHPStan\Type\UnionType; +use PhpParser\Node\Scalar\String_; use Rector\NodeAnalyzer\ArgsAnalyzer; -use Rector\NodeTypeResolver\Node\AttributeKey; -use Rector\NodeTypeResolver\PHPStan\ParametersAcceptorSelectorVariantsWrapper; -use Rector\Php81\NodeManipulator\NullToStrictStringIntConverter; use Rector\Rector\AbstractRector; -use Rector\Reflection\ReflectionResolver; use Rector\RuleDoc\CodeSample\CodeSample; use Rector\RuleDoc\RuleDefinition; use Rector\ValueObject\PhpVersionFeature; @@ -29,8 +21,6 @@ final class ArrayKeyExistsNullToEmptyStringRector extends AbstractRector implements MinPhpVersionInterface { public function __construct( - private readonly ReflectionResolver $reflectionResolver, - private readonly NullToStrictStringIntConverter $nullToStrictStringIntConverter, private readonly ArgsAnalyzer $argsAnalyzer ) { } @@ -71,49 +61,21 @@ public function refactor(Node $node): ?Node return null; } - $scope = $node->getAttribute(AttributeKey::SCOPE); - if (! $scope instanceof Scope) { - return null; - } - $args = $node->getArgs(); - if (count($args) !== 2) { return null; } - $classReflection = $scope->getClassReflection(); - $isTrait = $classReflection instanceof ClassReflection && $classReflection->isTrait(); - - $functionReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node); - if (! $functionReflection instanceof FunctionReflection) { - return null; - } - $argPosition = $this->argsAnalyzer->resolveArgPosition($args, 'key', 0); - $originalType = $this->getType($args[$argPosition]->value); + $activeArg = $args[$argPosition]; - if ($originalType instanceof UnionType) { - $withoutNullParameterType = TypeCombinator::removeNull($originalType); - if ($withoutNullParameterType->equals($originalType)) { - return null; - } + if (! $this->getType($activeArg->value)->isNull()->yes()) { + return null; } - $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); - $result = $this->nullToStrictStringIntConverter->convertIfNull( - $node, - $args, - $argPosition, - $isTrait, - $scope, - $parametersAcceptor - ); - if ($result instanceof Node) { - return $result; - } + $activeArg->value = new String_(''); - return null; + return $node; } public function provideMinPhpVersion(): int