From 85db284798787f8d3bf363786b836bc75129f904 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 30 Jul 2025 14:37:03 +0200 Subject: [PATCH 1/5] [type-declaration] Add AddReturnTypeFromTryCatchTypeRector --- ...ddReturnTypeFromTryCatchTypeRectorTest.php | 28 +++ .../Fixture/simple_try_catch.php.inc | 35 ++++ .../Fixture/skip_interface.php.inc | 9 + .../Fixture/skip_known_type.php.inc | 20 +++ .../config/configured_rule.php | 10 ++ ...gured_rule_with_treat_classes_as_final.php | 13 ++ .../config/intersection_config.php | 12 ++ .../config/union_config.php | 12 ++ .../AddReturnTypeFromTryCatchTypeRector.php | 160 ++++++++++++++++++ src/Config/Level/TypeDeclarationLevel.php | 2 + 10 files changed, 301 insertions(+) create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/AddReturnTypeFromTryCatchTypeRectorTest.php create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/simple_try_catch.php.inc create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_interface.php.inc create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_known_type.php.inc create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/configured_rule.php create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/configured_rule_with_treat_classes_as_final.php create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/intersection_config.php create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/union_config.php create mode 100644 rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector.php diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/AddReturnTypeFromTryCatchTypeRectorTest.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/AddReturnTypeFromTryCatchTypeRectorTest.php new file mode 100644 index 00000000000..ef0766b30d1 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/AddReturnTypeFromTryCatchTypeRectorTest.php @@ -0,0 +1,28 @@ +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/AddReturnTypeFromTryCatchTypeRector/Fixture/simple_try_catch.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/simple_try_catch.php.inc new file mode 100644 index 00000000000..e146312ebe4 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/simple_try_catch.php.inc @@ -0,0 +1,35 @@ + +----- + diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_interface.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_interface.php.inc new file mode 100644 index 00000000000..1d379ac1858 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_interface.php.inc @@ -0,0 +1,9 @@ +rule(AddReturnTypeFromTryCatchTypeRector::class); +}; diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/configured_rule_with_treat_classes_as_final.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/configured_rule_with_treat_classes_as_final.php new file mode 100644 index 00000000000..d2ef30bb41f --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/configured_rule_with_treat_classes_as_final.php @@ -0,0 +1,13 @@ +phpVersion(PhpVersionFeature::UNION_TYPES); + $rectorConfig->rule(AddMethodCallBasedStrictParamTypeRector::class); + $rectorConfig->treatClassesAsFinal(); +}; diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/intersection_config.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/intersection_config.php new file mode 100644 index 00000000000..5f335441e6d --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/intersection_config.php @@ -0,0 +1,12 @@ +phpVersion(PhpVersionFeature::INTERSECTION_TYPES); + $rectorConfig->rule(AddMethodCallBasedStrictParamTypeRector::class); +}; diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/union_config.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/union_config.php new file mode 100644 index 00000000000..17e72de655d --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/union_config.php @@ -0,0 +1,12 @@ +phpVersion(PhpVersionFeature::UNION_TYPES); + $rectorConfig->rule(AddMethodCallBasedStrictParamTypeRector::class); +}; diff --git a/rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector.php b/rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector.php new file mode 100644 index 00000000000..c89b690c92e --- /dev/null +++ b/rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector.php @@ -0,0 +1,160 @@ +> + */ + public function getNodeTypes(): array + { + return [ClassMethod::class]; + } + + /** + * @param ClassMethod $node + */ + public function refactor(Node $node): ?Node + { + // better nothing to do + if ($node->isAbstract()) { + return null; + } + + // already known type + if ($node->returnType instanceof \PhpParser\Node) { + return null; + } + + $scope = ScopeFetcher::fetch($node); + $classReflection = $scope->getClassReflection(); + if (! $classReflection instanceof ClassReflection) { + return null; + } + + // skip interfaces and traits + if (! $classReflection->isClass()) { + return null; + } + + $tryReturnType = null; + $catchReturnTypes = []; + + foreach ((array) $node->stmts as $classMethodStmt) { + if (! $classMethodStmt instanceof Node\Stmt\TryCatch) { + continue; + } + + $tryCatch = $classMethodStmt; + $tryReturnType = $this->matchReturnType($tryCatch); + + foreach ($tryCatch->catches as $catch) { + $currentCatchType = $this->matchReturnType($catch); + + // each catch must have type + if (! $currentCatchType instanceof \PHPStan\Type\Type) { + return null; + } + + $catchReturnTypes[] = $currentCatchType; + } + } + + if (! $tryReturnType instanceof \PHPStan\Type\Type) { + return null; + } + + foreach ($catchReturnTypes as $catchReturnType) { + if (! $this->typeComparator->areTypesEqual($catchReturnType, $tryReturnType)) { + return null; + } + } + + $returnType = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($tryReturnType, TypeKind::RETURN); + if (! $returnType instanceof \PhpParser\Node) { + return null; + } + + $node->returnType = $returnType; + return $node; + } + + private function matchReturnType(Node\Stmt\TryCatch|Node\Stmt\Catch_ $tryOrCatch): ?\PHPStan\Type\Type + { + foreach ($tryOrCatch->stmts as $stmt) { + if (! $stmt instanceof Node\Stmt\Return_) { + continue; + } + + if (! $stmt->expr instanceof Node\Expr) { + continue; + } + + return $this->getType($stmt->expr); + } + + return null; + } +} diff --git a/src/Config/Level/TypeDeclarationLevel.php b/src/Config/Level/TypeDeclarationLevel.php index 0728c1c7ca5..a9d34e64c88 100644 --- a/src/Config/Level/TypeDeclarationLevel.php +++ b/src/Config/Level/TypeDeclarationLevel.php @@ -18,6 +18,7 @@ use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeBasedOnPHPUnitDataProviderRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddParamTypeFromPropertyTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeDeclarationBasedOnParentClassMethodRector; +use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnTypeFromTryCatchTypeRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddVoidReturnTypeWhereNoReturnRector; use Rector\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromBooleanConstReturnsRector; use Rector\TypeDeclaration\Rector\ClassMethod\BoolReturnTypeFromBooleanStrictReturnsRector; @@ -108,6 +109,7 @@ final class TypeDeclarationLevel AddParamTypeBasedOnPHPUnitDataProviderRector::class, TypedPropertyFromStrictSetUpRector::class, ReturnTypeFromStrictNativeCallRector::class, + AddReturnTypeFromTryCatchTypeRector::class, ReturnTypeFromStrictTypedCallRector::class, ChildDoctrineRepositoryClassTypeRector::class, From 80038cd21252e548df8a94a38f81c033f8227606 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 30 Jul 2025 15:00:44 +0200 Subject: [PATCH 2/5] use ClassMethodReturnTypeOverrideGuard --- .../Fixture/skip_if_no_catch.php.inc | 15 ++++++ .../AddReturnTypeFromTryCatchTypeRector.php | 48 +++++++++---------- 2 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_if_no_catch.php.inc diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_if_no_catch.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_if_no_catch.php.inc new file mode 100644 index 00000000000..ae456d0762d --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_if_no_catch.php.inc @@ -0,0 +1,15 @@ +isAbstract()) { - return null; - } - - // already known type - if ($node->returnType instanceof \PhpParser\Node) { - return null; - } - $scope = ScopeFetcher::fetch($node); - $classReflection = $scope->getClassReflection(); - if (! $classReflection instanceof ClassReflection) { + if ($this->classMethodReturnTypeOverrideGuard->shouldSkipClassMethod($node, $scope)) { return null; } - // skip interfaces and traits - if (! $classReflection->isClass()) { + // already known type + if ($node->returnType instanceof Node) { return null; } @@ -103,7 +98,12 @@ public function refactor(Node $node): ?Node $catchReturnTypes = []; foreach ((array) $node->stmts as $classMethodStmt) { - if (! $classMethodStmt instanceof Node\Stmt\TryCatch) { + if (! $classMethodStmt instanceof TryCatch) { + continue; + } + + // skip if there is no catch + if ($classMethodStmt->catches === []) { continue; } @@ -114,7 +114,7 @@ public function refactor(Node $node): ?Node $currentCatchType = $this->matchReturnType($catch); // each catch must have type - if (! $currentCatchType instanceof \PHPStan\Type\Type) { + if (! $currentCatchType instanceof Type) { return null; } @@ -122,7 +122,7 @@ public function refactor(Node $node): ?Node } } - if (! $tryReturnType instanceof \PHPStan\Type\Type) { + if (! $tryReturnType instanceof Type) { return null; } @@ -133,7 +133,7 @@ public function refactor(Node $node): ?Node } $returnType = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($tryReturnType, TypeKind::RETURN); - if (! $returnType instanceof \PhpParser\Node) { + if (! $returnType instanceof Node) { return null; } @@ -141,14 +141,14 @@ public function refactor(Node $node): ?Node return $node; } - private function matchReturnType(Node\Stmt\TryCatch|Node\Stmt\Catch_ $tryOrCatch): ?\PHPStan\Type\Type + private function matchReturnType(TryCatch|Catch_ $tryOrCatch): ?Type { foreach ($tryOrCatch->stmts as $stmt) { - if (! $stmt instanceof Node\Stmt\Return_) { + if (! $stmt instanceof Return_) { continue; } - if (! $stmt->expr instanceof Node\Expr) { + if (! $stmt->expr instanceof Expr) { continue; } From 652a93fb8233964adf394b5e4e69ee882c17d256 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 30 Jul 2025 16:29:55 +0200 Subject: [PATCH 3/5] skip silent void --- .../Fixture/skip_doc_type.php.inc | 23 +++++++++++++++++++ .../Fixture/skip_silent_void.php.inc | 19 +++++++++++++++ .../AddReturnTypeFromTryCatchTypeRector.php | 12 ++++++++-- 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_doc_type.php.inc create mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_silent_void.php.inc diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_doc_type.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_doc_type.php.inc new file mode 100644 index 00000000000..29f9b436f08 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_doc_type.php.inc @@ -0,0 +1,23 @@ +getIntDoc(); + } + } + + /** + * @return int + */ + private function getIntDoc() + { + return mt_rand(0, 1) ? 'string' : 1; + } +} diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_silent_void.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_silent_void.php.inc new file mode 100644 index 00000000000..d42db7f6ec3 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/Fixture/skip_silent_void.php.inc @@ -0,0 +1,19 @@ +betterNodeFinder->findReturnsScoped($node); + if (! $this->returnAnalyzer->hasOnlyReturnWithExpr($node, $returns)) { + return null; + } + foreach ((array) $node->stmts as $classMethodStmt) { if (! $classMethodStmt instanceof TryCatch) { continue; @@ -152,7 +160,7 @@ private function matchReturnType(TryCatch|Catch_ $tryOrCatch): ?Type continue; } - return $this->getType($stmt->expr); + return $this->nodeTypeResolver->getType($stmt->expr); } return null; From 00db9a128c26ef96835934ff3ee0f29b5f8aca5b Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 30 Jul 2025 16:38:39 +0200 Subject: [PATCH 4/5] finalize classes --- .../Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php | 2 +- tests/Configuration/Source/RemoveDoubleAssignRector.php | 2 +- .../FileSystem/FilesFinder/SourceWithSuffix/SomeController.php | 2 +- .../FileSystem/FilesFinder/SourceWithSuffix/SomeRepository.php | 2 +- .../FilesFinder/SourceWithSuffix/other_unrelated_file.php | 2 +- tests/Issues/AutoImport/Source/Docblock/DateTime.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php b/rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php index 7c27c13c837..853a7148cc7 100644 --- a/rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php +++ b/rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php @@ -28,7 +28,7 @@ /** * @see \Rector\Tests\Transform\Rector\ArrayDimFetch\ArrayDimFetchToMethodCallRector\ArrayDimFetchToMethodCallRectorTest */ -class ArrayDimFetchToMethodCallRector extends AbstractRector implements ConfigurableRectorInterface +final class ArrayDimFetchToMethodCallRector extends AbstractRector implements ConfigurableRectorInterface { /** * @var ArrayDimFetchToMethodCall[] diff --git a/tests/Configuration/Source/RemoveDoubleAssignRector.php b/tests/Configuration/Source/RemoveDoubleAssignRector.php index 90451779eb2..4d6c05bdc49 100644 --- a/tests/Configuration/Source/RemoveDoubleAssignRector.php +++ b/tests/Configuration/Source/RemoveDoubleAssignRector.php @@ -9,7 +9,7 @@ /** * Dummy rector with same class name as an official one */ -class RemoveDoubleAssignRector extends AbstractRector +final class RemoveDoubleAssignRector extends AbstractRector { public function getRuleDefinition(): RuleDefinition { diff --git a/tests/FileSystem/FilesFinder/SourceWithSuffix/SomeController.php b/tests/FileSystem/FilesFinder/SourceWithSuffix/SomeController.php index 818c388f626..94bc266f596 100644 --- a/tests/FileSystem/FilesFinder/SourceWithSuffix/SomeController.php +++ b/tests/FileSystem/FilesFinder/SourceWithSuffix/SomeController.php @@ -2,6 +2,6 @@ namespace FileSystem\FilesFinder\SourceWithSuffix; -class SomeController +final class SomeController { } diff --git a/tests/FileSystem/FilesFinder/SourceWithSuffix/SomeRepository.php b/tests/FileSystem/FilesFinder/SourceWithSuffix/SomeRepository.php index 9103bc6e35a..7e81cc91731 100644 --- a/tests/FileSystem/FilesFinder/SourceWithSuffix/SomeRepository.php +++ b/tests/FileSystem/FilesFinder/SourceWithSuffix/SomeRepository.php @@ -2,6 +2,6 @@ namespace FileSystem\FilesFinder\SourceWithSuffix; -class SomeRepository +final class SomeRepository { } diff --git a/tests/FileSystem/FilesFinder/SourceWithSuffix/other_unrelated_file.php b/tests/FileSystem/FilesFinder/SourceWithSuffix/other_unrelated_file.php index 726c3e00df4..577e97b30a0 100644 --- a/tests/FileSystem/FilesFinder/SourceWithSuffix/other_unrelated_file.php +++ b/tests/FileSystem/FilesFinder/SourceWithSuffix/other_unrelated_file.php @@ -2,6 +2,6 @@ namespace FileSystem\FilesFinder\SourceWithSuffix; -class OtherUnrelatedFile +final class OtherUnrelatedFile { } diff --git a/tests/Issues/AutoImport/Source/Docblock/DateTime.php b/tests/Issues/AutoImport/Source/Docblock/DateTime.php index 761156d7529..1e780410835 100644 --- a/tests/Issues/AutoImport/Source/Docblock/DateTime.php +++ b/tests/Issues/AutoImport/Source/Docblock/DateTime.php @@ -4,6 +4,6 @@ namespace Rector\Tests\Issues\AutoImport\Source\Docblock; -class DateTime +final class DateTime { } From c2d96ae44da89069664da550909e12c51d6fb1f6 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Wed, 30 Jul 2025 16:38:52 +0200 Subject: [PATCH 5/5] [ci] fail on missed final class --- .github/workflows/code_analysis.yaml | 2 +- ...gured_rule_with_treat_classes_as_final.php | 13 ------- .../config/intersection_config.php | 12 ------- .../config/union_config.php | 12 ------- .../ArrayDimFetchToMethodCallRector.php | 36 +++++++++---------- .../AddReturnTypeFromTryCatchTypeRector.php | 2 +- 6 files changed, 20 insertions(+), 57 deletions(-) delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/configured_rule_with_treat_classes_as_final.php delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/intersection_config.php delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/union_config.php diff --git a/.github/workflows/code_analysis.yaml b/.github/workflows/code_analysis.yaml index ddf1bf381e2..c9877225baf 100644 --- a/.github/workflows/code_analysis.yaml +++ b/.github/workflows/code_analysis.yaml @@ -50,7 +50,7 @@ jobs: - name: 'Finalize classes' - run: vendor/bin/swiss-knife finalize-classes src tests + run: vendor/bin/swiss-knife finalize-classes src tests --dry-run - name: 'Detect composer dependency issues' diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/configured_rule_with_treat_classes_as_final.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/configured_rule_with_treat_classes_as_final.php deleted file mode 100644 index d2ef30bb41f..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/configured_rule_with_treat_classes_as_final.php +++ /dev/null @@ -1,13 +0,0 @@ -phpVersion(PhpVersionFeature::UNION_TYPES); - $rectorConfig->rule(AddMethodCallBasedStrictParamTypeRector::class); - $rectorConfig->treatClassesAsFinal(); -}; diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/intersection_config.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/intersection_config.php deleted file mode 100644 index 5f335441e6d..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/intersection_config.php +++ /dev/null @@ -1,12 +0,0 @@ -phpVersion(PhpVersionFeature::INTERSECTION_TYPES); - $rectorConfig->rule(AddMethodCallBasedStrictParamTypeRector::class); -}; diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/union_config.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/union_config.php deleted file mode 100644 index 17e72de655d..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector/config/union_config.php +++ /dev/null @@ -1,12 +0,0 @@ -phpVersion(PhpVersionFeature::UNION_TYPES); - $rectorConfig->rule(AddMethodCallBasedStrictParamTypeRector::class); -}; diff --git a/rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php b/rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php index 853a7148cc7..5a949d5f9da 100644 --- a/rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php +++ b/rules/Transform/Rector/ArrayDimFetch/ArrayDimFetchToMethodCallRector.php @@ -101,16 +101,16 @@ public function configure(array $configuration): void $this->arrayDimFetchToMethodCalls = $configuration; } - private function handleIsset(Isset_ $node): Expr|int|null + private function handleIsset(Isset_ $isset): Expr|int|null { $issets = []; $exprs = []; - foreach ($node->vars as $var) { + foreach ($isset->vars as $var) { if ($var instanceof ArrayDimFetch) { $methodCall = $this->getMethodCall($var, 'exists'); - if ($methodCall !== null) { + if ($methodCall instanceof MethodCall) { $exprs[] = $methodCall; continue; } @@ -124,13 +124,13 @@ private function handleIsset(Isset_ $node): Expr|int|null } if ($issets !== []) { - $node->vars = $issets; - array_unshift($exprs, $node); + $isset->vars = $issets; + array_unshift($exprs, $isset); } return array_reduce( $exprs, - fn (?Expr $carry, Expr $expr) => $carry === null ? $expr : new BooleanAnd($carry, $expr), + fn (?Expr $carry, Expr $expr): Isset_|MethodCall|BooleanAnd => $carry instanceof Expr ? new BooleanAnd($carry, $expr) : $expr, null, ); } @@ -138,16 +138,16 @@ private function handleIsset(Isset_ $node): Expr|int|null /** * @return Stmt[]|int */ - private function handleUnset(Unset_ $node): array|int + private function handleUnset(Unset_ $unset): array|int { $unsets = []; $stmts = []; - foreach ($node->vars as $var) { + foreach ($unset->vars as $var) { if ($var instanceof ArrayDimFetch) { $methodCall = $this->getMethodCall($var, 'unset'); - if ($methodCall !== null) { + if ($methodCall instanceof MethodCall) { $stmts[] = new Expression($methodCall); continue; } @@ -161,8 +161,8 @@ private function handleUnset(Unset_ $node): array|int } if ($unsets !== []) { - $node->vars = $unsets; - array_unshift($stmts, $node); + $unset->vars = $unsets; + array_unshift($stmts, $unset); } return $stmts; @@ -171,14 +171,14 @@ private function handleUnset(Unset_ $node): array|int /** * @param 'get'|'set'|'exists'|'unset' $action */ - private function getMethodCall(ArrayDimFetch $fetch, string $action, ?Expr $value = null): ?MethodCall + private function getMethodCall(ArrayDimFetch $arrayDimFetch, string $action, ?Expr $expr = null): ?MethodCall { - if (!$fetch->dim instanceof Node) { + if (!$arrayDimFetch->dim instanceof Node) { return null; } foreach ($this->arrayDimFetchToMethodCalls as $arrayDimFetchToMethodCall) { - if (!$this->isObjectType($fetch->var, $arrayDimFetchToMethodCall->getObjectType())) { + if (!$this->isObjectType($arrayDimFetch->var, $arrayDimFetchToMethodCall->getObjectType())) { continue; } @@ -193,13 +193,13 @@ private function getMethodCall(ArrayDimFetch $fetch, string $action, ?Expr $valu continue; } - $args = [new Arg($fetch->dim)]; + $args = [new Arg($arrayDimFetch->dim)]; - if ($value instanceof Expr) { - $args[] = new Arg($value); + if ($expr instanceof Expr) { + $args[] = new Arg($expr); } - return new MethodCall($fetch->var, $method, $args); + return new MethodCall($arrayDimFetch->var, $method, $args); } return null; diff --git a/rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector.php b/rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector.php index 2dbbdeb8d08..6f1eeacf62b 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/AddReturnTypeFromTryCatchTypeRector.php @@ -160,7 +160,7 @@ private function matchReturnType(TryCatch|Catch_ $tryOrCatch): ?Type continue; } - return $this->nodeTypeResolver->getType($stmt->expr); + return $this->nodeTypeResolver->getNativeType($stmt->expr); } return null;