From a2f70dfc3da091c24b12537fbfe05b4267c5c4d4 Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Fri, 25 Sep 2020 19:48:31 +0900 Subject: [PATCH] KT-41298 "Remove redundant 'with' call" intention works incorrectly with non-local returns and single-expression functions (#3713) * Remove redundant 'with' call: remove redundant 'return' keyword #KT-41298 Fixed --- .../inspections/RedundantWithInspection.kt | 22 ++++++++++++++++--- .../redundantWith/asInitializer.kt | 5 +++++ .../redundantWith/asInitializer.kt.after | 5 +++++ .../asInitializerWithSingleReturn.kt | 5 +++++ .../asInitializerWithSingleReturn.kt.after | 3 +++ .../LocalInspectionTestGenerated.java | 10 +++++++++ 6 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 idea/testData/inspectionsLocal/redundantWith/asInitializer.kt create mode 100644 idea/testData/inspectionsLocal/redundantWith/asInitializer.kt.after create mode 100644 idea/testData/inspectionsLocal/redundantWith/asInitializerWithSingleReturn.kt create mode 100644 idea/testData/inspectionsLocal/redundantWith/asInitializerWithSingleReturn.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt index 05bcc6a9de2..3733cc6d73a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/RedundantWithInspection.kt @@ -17,6 +17,8 @@ import org.jetbrains.kotlin.idea.core.moveCaret import org.jetbrains.kotlin.idea.core.replaced import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType +import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall @@ -85,8 +87,22 @@ private class RemoveRedundantWithFix : LocalQuickFix { override fun applyFix(project: Project, descriptor: ProblemDescriptor) { val callExpression = descriptor.psiElement.parent as? KtCallExpression ?: return - val lambdaBody = callExpression.valueArguments.getOrNull(1)?.lambdaExpression()?.bodyExpression ?: return - val replaced = callExpression.replaced(lambdaBody) - replaced.findExistingEditor()?.moveCaret(replaced.startOffset) + val lambdaExpression = callExpression.valueArguments.getOrNull(1)?.lambdaExpression() ?: return + val lambdaBody = lambdaExpression.bodyExpression ?: return + val declaration = callExpression.getStrictParentOfType() + val replaced = if (declaration?.equalsToken != null && KtPsiUtil.deparenthesize(declaration.bodyExpression) == callExpression) { + val singleReturnedExpression = (lambdaBody.statements.singleOrNull() as? KtReturnExpression)?.returnedExpression + if (singleReturnedExpression != null) { + callExpression.replaced(singleReturnedExpression) + } else { + declaration.equalsToken?.delete() + declaration.bodyExpression?.replaced(KtPsiFactory(project).createSingleStatementBlock(lambdaBody)) + } + } else { + callExpression.replaced(lambdaBody) + } + if (replaced != null) { + replaced.findExistingEditor()?.moveCaret(replaced.startOffset) + } } } diff --git a/idea/testData/inspectionsLocal/redundantWith/asInitializer.kt b/idea/testData/inspectionsLocal/redundantWith/asInitializer.kt new file mode 100644 index 00000000000..64997c38f67 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantWith/asInitializer.kt @@ -0,0 +1,5 @@ +// WITH_RUNTIME +fun test(): Int = with("") { + println() + return 42 +} diff --git a/idea/testData/inspectionsLocal/redundantWith/asInitializer.kt.after b/idea/testData/inspectionsLocal/redundantWith/asInitializer.kt.after new file mode 100644 index 00000000000..c081878c993 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantWith/asInitializer.kt.after @@ -0,0 +1,5 @@ +// WITH_RUNTIME +fun test(): Int { + println() + return 42 +} diff --git a/idea/testData/inspectionsLocal/redundantWith/asInitializerWithSingleReturn.kt b/idea/testData/inspectionsLocal/redundantWith/asInitializerWithSingleReturn.kt new file mode 100644 index 00000000000..8788b0b41a6 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantWith/asInitializerWithSingleReturn.kt @@ -0,0 +1,5 @@ +// WITH_RUNTIME +fun foo(s: String): Int = + with("s") { + return 42 + } \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/redundantWith/asInitializerWithSingleReturn.kt.after b/idea/testData/inspectionsLocal/redundantWith/asInitializerWithSingleReturn.kt.after new file mode 100644 index 00000000000..34b0b68eb17 --- /dev/null +++ b/idea/testData/inspectionsLocal/redundantWith/asInitializerWithSingleReturn.kt.after @@ -0,0 +1,3 @@ +// WITH_RUNTIME +fun foo(s: String): Int = + 42 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index c4071687dad..62ed03a94b8 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -9221,6 +9221,16 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/redundantWith"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true); } + @TestMetadata("asInitializer.kt") + public void testAsInitializer() throws Exception { + runTest("idea/testData/inspectionsLocal/redundantWith/asInitializer.kt"); + } + + @TestMetadata("asInitializerWithSingleReturn.kt") + public void testAsInitializerWithSingleReturn() throws Exception { + runTest("idea/testData/inspectionsLocal/redundantWith/asInitializerWithSingleReturn.kt"); + } + @TestMetadata("emptyExpressionInReturn.kt") public void testEmptyExpressionInReturn() throws Exception { runTest("idea/testData/inspectionsLocal/redundantWith/emptyExpressionInReturn.kt");