diff --git a/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/empty_brackets.php.inc b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/empty_brackets.php.inc index a9d94007688..2a51e74803e 100644 --- a/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/empty_brackets.php.inc +++ b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/empty_brackets.php.inc @@ -8,8 +8,8 @@ class EmptyBrackets { try { $someCode = 1; - } catch (Throwable $throwable) { - throw new AnotherException; + } catch (\Throwable $throwable) { + throw new \RuntimeException; } } } @@ -26,8 +26,8 @@ class EmptyBrackets { try { $someCode = 1; - } catch (Throwable $throwable) { - throw new AnotherException($throwable->getMessage(), $throwable->getCode(), $throwable); + } catch (\Throwable $throwable) { + throw new \RuntimeException($throwable->getMessage(), $throwable->getCode(), $throwable); } } } diff --git a/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/fixture.php.inc b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/fixture.php.inc index fcac2a63b66..8e1085cee31 100644 --- a/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/fixture.php.inc +++ b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/fixture.php.inc @@ -8,8 +8,8 @@ class Fixture { try { $someCode = 1; - } catch (Throwable $throwable) { - throw new AnotherException('ups'); + } catch (\Throwable $throwable) { + throw new \RuntimeException('ups'); } } } @@ -26,8 +26,8 @@ class Fixture { try { $someCode = 1; - } catch (Throwable $throwable) { - throw new AnotherException('ups', $throwable->getCode(), $throwable); + } catch (\Throwable $throwable) { + throw new \RuntimeException('ups', $throwable->getCode(), $throwable); } } } diff --git a/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/named_argument.php.inc b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/named_argument.php.inc index 0e9b6859aa1..792b460802d 100644 --- a/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/named_argument.php.inc +++ b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/named_argument.php.inc @@ -9,7 +9,7 @@ class NamedArgument try { $this->run(); }catch(\Throwable $throwable) { - throw new LogicException('Some exception', previous: $throwable); + throw new \LogicException('Some exception', previous: $throwable); } } } @@ -27,7 +27,7 @@ class NamedArgument try { $this->run(); }catch(\Throwable $throwable) { - throw new LogicException('Some exception', $throwable->getCode(), previous: $throwable); + throw new \LogicException('Some exception', $throwable->getCode(), previous: $throwable); } } } diff --git a/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/named_argument_for_message.php.inc b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/named_argument_for_message.php.inc index bd3ca8a1a25..03ba153ebc7 100644 --- a/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/named_argument_for_message.php.inc +++ b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/named_argument_for_message.php.inc @@ -9,7 +9,7 @@ class NamedArgumentForMessage try { $this->run(); }catch(\Throwable $throwable) { - throw new LogicException(message: 'Some exception'); + throw new \LogicException(message: 'Some exception'); } } } @@ -27,7 +27,7 @@ class NamedArgumentForMessage try { $this->run(); }catch(\Throwable $throwable) { - throw new LogicException(message: 'Some exception', code: $throwable->getCode(), previous: $throwable); + throw new \LogicException(message: 'Some exception', code: $throwable->getCode(), previous: $throwable); } } } diff --git a/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/skip_custom_exception_no_code_param.php.inc b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/skip_custom_exception_no_code_param.php.inc new file mode 100644 index 00000000000..7c8ffbe7677 --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Catch_/ThrowWithPreviousExceptionRector/Fixture/skip_custom_exception_no_code_param.php.inc @@ -0,0 +1,27 @@ +getCode(), $throwable); + throw new \RuntimeException('ups', $throwable->getCode(), $throwable); } } } @@ -142,34 +142,47 @@ private function refactorThrow(Throw_ $throw, Variable $caughtThrowableVariable) $messageArgument = $new->args[0] ?? null; $shouldUseNamedArguments = $messageArgument instanceof Arg && $messageArgument->name instanceof Identifier; + $hasChanged = false; if (! isset($new->args[0])) { // get previous message $getMessageMethodCall = new MethodCall($caughtThrowableVariable, 'getMessage'); $new->args[0] = new Arg($getMessageMethodCall); + $hasChanged = true; } elseif ($new->args[0] instanceof Arg && $new->args[0]->name instanceof Identifier && $new->args[0]->name->toString() === 'previous' && $this->nodeComparator->areNodesEqual( $new->args[0]->value, $caughtThrowableVariable )) { $new->args[0]->name->name = 'message'; $new->args[0]->value = new MethodCall($caughtThrowableVariable, 'getMessage'); + $hasChanged = true; } if (! isset($new->getArgs()[1])) { - // get previous code - $new->args[1] = new Arg( - new MethodCall($caughtThrowableVariable, 'getCode'), - name: $shouldUseNamedArguments ? new Identifier('code') : null - ); + if ($this->hasCodeParameter($new->class)) { + // get previous code + $new->args[1] = new Arg( + new MethodCall($caughtThrowableVariable, 'getCode'), + name: $shouldUseNamedArguments ? new Identifier('code') : null + ); + $hasChanged = true; + } else { + return null; + } } /** @var Arg $arg1 */ $arg1 = $new->args[1]; if ($arg1->name instanceof Identifier && $arg1->name->toString() === 'previous') { - $new->args[1] = new Arg( - new MethodCall($caughtThrowableVariable, 'getCode'), - name: $shouldUseNamedArguments ? new Identifier('code') : null - ); - $new->args[$exceptionArgumentPosition] = $arg1; + if ($this->hasCodeParameter($new->class)) { + $new->args[1] = new Arg( + new MethodCall($caughtThrowableVariable, 'getCode'), + name: $shouldUseNamedArguments ? new Identifier('code') : null + ); + $new->args[$exceptionArgumentPosition] = $arg1; + $hasChanged = true; + } elseif (! $hasChanged) { + return null; + } } else { $new->args[$exceptionArgumentPosition] = new Arg( $caughtThrowableVariable, @@ -184,6 +197,34 @@ private function refactorThrow(Throw_ $throw, Variable $caughtThrowableVariable) return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN; } + private function hasCodeParameter(Name $exceptionName): bool + { + $className = $this->getName($exceptionName); + if (! $this->reflectionProvider->hasClass($className)) { + return false; + } + + $classReflection = $this->reflectionProvider->getClass($className); + $construct = $classReflection->hasMethod(MethodName::CONSTRUCT); + + if (! $construct) { + return false; + } + + $extendedMethodReflection = $classReflection->getConstructor(); + $extendedParametersAcceptor = ParametersAcceptorSelector::combineAcceptors( + $extendedMethodReflection->getVariants() + ); + + foreach ($extendedParametersAcceptor->getParameters() as $extendedParameterReflection) { + if ($extendedParameterReflection->getName() === 'code') { + return true; + } + } + + return false; + } + private function resolveExceptionArgumentPosition(Name $exceptionName): ?int { $className = $this->getName($exceptionName); diff --git a/rules/Php73/Rector/FuncCall/JsonThrowOnErrorRector.php b/rules/Php73/Rector/FuncCall/JsonThrowOnErrorRector.php index 38342c24806..32eafaacdc7 100644 --- a/rules/Php73/Rector/FuncCall/JsonThrowOnErrorRector.php +++ b/rules/Php73/Rector/FuncCall/JsonThrowOnErrorRector.php @@ -29,8 +29,6 @@ final class JsonThrowOnErrorRector extends AbstractRector implements MinPhpVersi { private const array FLAGS = ['JSON_THROW_ON_ERROR']; - private bool $hasChanged = false; - public function __construct( private readonly ValueResolver $valueResolver, private readonly BetterNodeFinder $betterNodeFinder @@ -77,9 +75,9 @@ public function refactor(Node $node): ?Node return null; } - $this->hasChanged = false; + $hasChanged = false; - $this->traverseNodesWithCallable($node, function (Node $currentNode): ?FuncCall { + $this->traverseNodesWithCallable($node, function (Node $currentNode) use (&$hasChanged): ?FuncCall { if (! $currentNode instanceof FuncCall) { return null; } @@ -89,17 +87,17 @@ public function refactor(Node $node): ?Node } if ($this->isName($currentNode, 'json_encode')) { - return $this->processJsonEncode($currentNode); + return $this->processJsonEncode($currentNode, $hasChanged); } if ($this->isName($currentNode, 'json_decode')) { - return $this->processJsonDecode($currentNode); + return $this->processJsonDecode($currentNode, $hasChanged); } return null; }); - if ($this->hasChanged) { + if ($hasChanged) { return $node; } @@ -134,7 +132,7 @@ private function shouldSkipFuncCall(FuncCall $funcCall): bool return $this->isFirstValueStringOrArray($funcCall); } - private function processJsonEncode(FuncCall $funcCall): FuncCall + private function processJsonEncode(FuncCall $funcCall, bool &$hasChanged): FuncCall { $flags = []; if (isset($funcCall->args[1])) { @@ -145,14 +143,14 @@ private function processJsonEncode(FuncCall $funcCall): FuncCall $newArg = $this->getArgWithFlags($flags); if ($newArg instanceof Arg) { - $this->hasChanged = true; + $hasChanged = true; $funcCall->args[1] = $newArg; } return $funcCall; } - private function processJsonDecode(FuncCall $funcCall): FuncCall + private function processJsonDecode(FuncCall $funcCall, bool &$hasChanged): FuncCall { $flags = []; if (isset($funcCall->args[3])) { @@ -172,7 +170,7 @@ private function processJsonDecode(FuncCall $funcCall): FuncCall $newArg = $this->getArgWithFlags($flags); if ($newArg instanceof Arg) { - $this->hasChanged = true; + $hasChanged = true; $funcCall->args[3] = $newArg; } diff --git a/src/ChangesReporting/Output/GitlabOutputFormatter.php b/src/ChangesReporting/Output/GitlabOutputFormatter.php index b0e8530153b..d43ac4ba2a2 100644 --- a/src/ChangesReporting/Output/GitlabOutputFormatter.php +++ b/src/ChangesReporting/Output/GitlabOutputFormatter.php @@ -30,7 +30,7 @@ private const string ERROR_SEVERITY_MINOR = 'minor'; public function __construct( - private Filehasher $filehasher, + private FileHasher $filehasher, ) { }