diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplacePutWithAssignmentInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplacePutWithAssignmentInspection.kt index 5481b218eb6..8ef97775b5c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ReplacePutWithAssignmentInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ReplacePutWithAssignmentInspection.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.intentions.callExpression import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall @@ -31,7 +32,7 @@ import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getExplicitReceiverVa import org.jetbrains.kotlin.resolve.descriptorUtil.isSubclassOf class ReplacePutWithAssignmentInspection : AbstractApplicabilityBasedInspection( - KtDotQualifiedExpression::class.java + KtDotQualifiedExpression::class.java ) { override fun isApplicable(element: KtDotQualifiedExpression): Boolean { @@ -52,10 +53,20 @@ class ReplacePutWithAssignmentInspection : AbstractApplicabilityBasedInspection< override fun applyTo(element: PsiElement, project: Project, editor: Editor?) { val expression = element.getParentOfType(strict = false) ?: return val valueArguments = expression.callExpression?.valueArguments ?: return - expression.replace(KtPsiFactory(expression).createExpressionByPattern("$0[$1] = $2", - expression.receiverExpression, - valueArguments[0]?.getArgumentExpression() ?: return, - valueArguments[1]?.getArgumentExpression() ?: return)) + val firstArg = valueArguments[0]?.getArgumentExpression() ?: return + val secondArg = valueArguments[1]?.getArgumentExpression() ?: return + val label = if (secondArg is KtLambdaExpression) { + val returnLabel = secondArg.findDescendantOfType()?.getLabelName() + compatibleNames.firstOrNull { it == returnLabel }?.plus("@") ?: "" + } else "" + expression.replace( + KtPsiFactory(expression).createExpressionByPattern( + "$0[$1] = $label$2", + expression.receiverExpression, + firstArg, + secondArg + ) + ) } override fun inspectionTarget(element: KtDotQualifiedExpression) = element.callExpression?.calleeExpression ?: element diff --git a/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn.kt b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn.kt new file mode 100644 index 00000000000..0a02b21bf8b --- /dev/null +++ b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn.kt @@ -0,0 +1,10 @@ +// WITH_RUNTIME + +fun test(b: Boolean) { + val map = mutableMapOf Unit>() + map.put("") { + if (b) { + return@put + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn.kt.after b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn.kt.after new file mode 100644 index 00000000000..920aeb6640e --- /dev/null +++ b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn.kt.after @@ -0,0 +1,10 @@ +// WITH_RUNTIME + +fun test(b: Boolean) { + val map = mutableMapOf Unit>() + map[""] = put@{ + if (b) { + return@put + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn2.kt b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn2.kt new file mode 100644 index 00000000000..1c838a5233b --- /dev/null +++ b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn2.kt @@ -0,0 +1,10 @@ +// WITH_RUNTIME + +fun test() { + val map = mutableMapOf Unit>() + map.put("") { + listOf(1).forEach { + return@forEach + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn2.kt.after b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn2.kt.after new file mode 100644 index 00000000000..a52986008ea --- /dev/null +++ b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn2.kt.after @@ -0,0 +1,10 @@ +// WITH_RUNTIME + +fun test() { + val map = mutableMapOf Unit>() + map[""] = { + listOf(1).forEach { + return@forEach + } + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn3.kt b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn3.kt new file mode 100644 index 00000000000..049d915e96b --- /dev/null +++ b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn3.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME + +fun test() { + val map = mutableMapOf Unit>() + map.put("") label@{ + return@label + } +} \ No newline at end of file diff --git a/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn3.kt.after b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn3.kt.after new file mode 100644 index 00000000000..937172f4a9a --- /dev/null +++ b/idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn3.kt.after @@ -0,0 +1,8 @@ +// WITH_RUNTIME + +fun test() { + val map = mutableMapOf Unit>() + map[""] = label@{ + return@label + } +} \ 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 3fc4018179c..9f244a3868a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -3951,6 +3951,24 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest { doTest(fileName); } + @TestMetadata("putLambdaHasLabeledReturn.kt") + public void testPutLambdaHasLabeledReturn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn.kt"); + doTest(fileName); + } + + @TestMetadata("putLambdaHasLabeledReturn2.kt") + public void testPutLambdaHasLabeledReturn2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn2.kt"); + doTest(fileName); + } + + @TestMetadata("putLambdaHasLabeledReturn3.kt") + public void testPutLambdaHasLabeledReturn3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/replacePutWithAssignment/putLambdaHasLabeledReturn3.kt"); + doTest(fileName); + } + @TestMetadata("putOnParameter.kt") public void testPutOnParameter() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/replacePutWithAssignment/putOnParameter.kt");