mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 06:39:38 +07:00
KTIJ-22971 [kotlin] Transform RemoveLabeledReturnInLambdaIntention into LabeledReturnAsLastExpressionInLambdaInspection
- convert intention to inspection, so it can be executed in the batch mode - move the inspection to the shared module for both K1 and K2 - move and adjust the testdata where needed ^KTIJ-22971 Fixed GitOrigin-RevId: e01f190aa70a1f440bb7d8b523b785d249b7e7de
This commit is contained in:
committed by
intellij-monorepo-bot
parent
e23937ffab
commit
fbf7da2525
@@ -2086,6 +2086,7 @@ inspection.kotlin.throwable.not.thrown.display.name=Throwable not thrown
|
||||
inspection.redundant.require.not.null.call.display.name=Redundant 'requireNotNull' or 'checkNotNull' call
|
||||
inspection.replace.range.start.end.inclusive.with.first.last.display.name=Boxed properties should be replaced with unboxed
|
||||
inspection.redundant.enum.constructor.invocation.display.name=Redundant enum constructor invocation
|
||||
inspection.labeled.return.on.last.expression.in.lambda.display.name=Labeled return on the last expression in a lambda
|
||||
inspection.replace.negated.is.empty.with.is.not.empty.display.name=Negated call can be simplified
|
||||
inspection.function.with.lambda.expression.body.display.name=Function with '= { ... }' and inferred return type
|
||||
inspection.suspend.function.on.coroutine.scope.display.name=Ambiguous coroutineContext due to CoroutineScope receiver of suspend function
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports labeled returns used on the last expressions in lambdas.
|
||||
|
||||
<p>Such returns are unnecessary and can be safely removed.</p>
|
||||
|
||||
<p><b>Example:</b></p>
|
||||
<pre><code>
|
||||
fun foo() {
|
||||
listOf(1,2,3).find {
|
||||
return@find true
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<p>After the quick-fix is applied:</p>
|
||||
<pre><code>
|
||||
fun foo() {
|
||||
listOf(1,2,3).find {
|
||||
true
|
||||
}
|
||||
}
|
||||
</code></pre>
|
||||
<!-- tooltip end -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +0,0 @@
|
||||
fun foo() {
|
||||
listOf(1,2,3).find {
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
fun foo() {
|
||||
listOf(1,2,3).find {
|
||||
<spot>return@find</spot> true
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
Removes a labeled return from the last expression in a lambda.
|
||||
</body>
|
||||
</html>
|
||||
@@ -315,5 +315,13 @@
|
||||
language="kotlin"
|
||||
key="inspection.control.flow.with.empty.body.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.codeInsight.inspections.shared.LabeledReturnAsLastExpressionInLambdaInspection"
|
||||
groupPath="Kotlin"
|
||||
groupBundle="messages.KotlinBundle" groupKey="group.names.redundant.constructs"
|
||||
enabledByDefault="true"
|
||||
level="INFORMATION"
|
||||
language="kotlin"
|
||||
key="inspection.labeled.return.on.last.expression.in.lambda.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.kotlin.idea.codeInsight.inspections.shared
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.codeInspection.util.InspectionMessage
|
||||
import com.intellij.codeInspection.util.IntentionFamilyName
|
||||
import com.intellij.modcommand.ModPsiUpdater
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.idea.base.psi.getParentLambdaLabelName
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.applicable.inspections.AbstractKotlinApplicableInspection
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.applicators.KotlinApplicabilityRange
|
||||
import org.jetbrains.kotlin.idea.codeinsights.impl.base.applicators.ApplicabilityRanges
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.kotlin.psi.KtReturnExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.returnExpressionVisitor
|
||||
|
||||
/**
|
||||
* Tests:
|
||||
* - [org.jetbrains.kotlin.idea.codeInsight.inspections.shared.SharedK1LocalInspectionTestGenerated.LabeledReturnAsLastExpressionInLambda]
|
||||
* - [org.jetbrains.kotlin.idea.k2.codeInsight.inspections.shared.SharedK2LocalInspectionTestGenerated.LabeledReturnAsLastExpressionInLambda]
|
||||
*/
|
||||
internal class LabeledReturnAsLastExpressionInLambdaInspection : AbstractKotlinApplicableInspection<KtReturnExpression>() {
|
||||
|
||||
override fun getProblemDescription(element: KtReturnExpression): @InspectionMessage String =
|
||||
KotlinBundle.message("inspection.labeled.return.on.last.expression.in.lambda.display.name")
|
||||
|
||||
override fun getActionFamilyName(): @IntentionFamilyName String =
|
||||
KotlinBundle.message("remove.labeled.return.from.last.expression.in.a.lambda")
|
||||
|
||||
override fun getActionName(element: KtReturnExpression): @InspectionMessage String {
|
||||
val labelName = element.getLabelName().orEmpty()
|
||||
|
||||
return KotlinBundle.message("remove.return.0", labelName)
|
||||
}
|
||||
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor =
|
||||
returnExpressionVisitor {
|
||||
visitTargetElement(it, holder, isOnTheFly)
|
||||
}
|
||||
|
||||
override fun isApplicableByPsi(element: KtReturnExpression): Boolean {
|
||||
val labelName = element.getLabelName() ?: return false
|
||||
val block = element.getStrictParentOfType<KtBlockExpression>() ?: return false
|
||||
if (block.statements.lastOrNull() != element) return false
|
||||
val callName = block.getParentLambdaLabelName() ?: return false
|
||||
if (labelName != callName) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getApplicabilityRange(): KotlinApplicabilityRange<KtReturnExpression> = ApplicabilityRanges.SELF
|
||||
|
||||
override fun apply(
|
||||
element: KtReturnExpression,
|
||||
project: Project,
|
||||
updater: ModPsiUpdater
|
||||
) {
|
||||
val returnedExpression = element.returnedExpression
|
||||
if (returnedExpression == null) {
|
||||
element.delete()
|
||||
} else {
|
||||
element.replace(returnedExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -516,6 +516,54 @@ public abstract class SharedK1LocalInspectionTestGenerated extends AbstractShare
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda")
|
||||
public static class LabeledReturnAsLastExpressionInLambda extends AbstractSharedK1LocalInspectionTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("labeledLambda.kt")
|
||||
public void testLabeledLambda() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/labeledLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleBlocks.kt")
|
||||
public void testMultipleBlocks() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/multipleBlocks.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normal.kt")
|
||||
public void testNormal() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/normal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notInsideLabeled.kt")
|
||||
public void testNotInsideLabeled() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/notInsideLabeled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notLabeled.kt")
|
||||
public void testNotLabeled() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/notLabeled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notLastLine.kt")
|
||||
public void testNotLastLine() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/notLastLine.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("outerLambda.kt")
|
||||
public void testOuterLambda() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/outerLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unit.kt")
|
||||
public void testUnit() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/unit.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/inspectionsLocal/redundantConstructorKeyword")
|
||||
public static class RedundantConstructorKeyword extends AbstractSharedK1LocalInspectionTest {
|
||||
|
||||
@@ -516,6 +516,54 @@ public abstract class SharedK2LocalInspectionTestGenerated extends AbstractShare
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda")
|
||||
public static class LabeledReturnAsLastExpressionInLambda extends AbstractSharedK2LocalInspectionTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("labeledLambda.kt")
|
||||
public void testLabeledLambda() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/labeledLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleBlocks.kt")
|
||||
public void testMultipleBlocks() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/multipleBlocks.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normal.kt")
|
||||
public void testNormal() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/normal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notInsideLabeled.kt")
|
||||
public void testNotInsideLabeled() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/notInsideLabeled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notLabeled.kt")
|
||||
public void testNotLabeled() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/notLabeled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notLastLine.kt")
|
||||
public void testNotLastLine() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/notLastLine.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("outerLambda.kt")
|
||||
public void testOuterLambda() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/outerLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unit.kt")
|
||||
public void testUnit() throws Exception {
|
||||
runTest("../testData/inspectionsLocal/labeledReturnAsLastExpressionInLambda/unit.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("../testData/inspectionsLocal/redundantConstructorKeyword")
|
||||
public static class RedundantConstructorKeyword extends AbstractSharedK2LocalInspectionTest {
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.codeInsight.inspections.shared.LabeledReturnAsLastExpressionInLambdaInspection
|
||||
@@ -1,5 +1,5 @@
|
||||
// WITH_STDLIB
|
||||
// IS_APPLICABLE: FALSE
|
||||
// PROBLEM: none
|
||||
|
||||
fun foo(): Boolean {
|
||||
return@foo <caret>true
|
||||
@@ -1,5 +1,5 @@
|
||||
// WITH_STDLIB
|
||||
// IS_APPLICABLE: FALSE
|
||||
// PROBLEM: none
|
||||
|
||||
fun foo(): Boolean {
|
||||
listOf(1,2,3).find {
|
||||
@@ -1,5 +1,5 @@
|
||||
// WITH_STDLIB
|
||||
// IS_APPLICABLE: FALSE
|
||||
// PROBLEM: none
|
||||
|
||||
fun foo() {
|
||||
listOf(1,2,3).find {
|
||||
@@ -1,5 +1,5 @@
|
||||
// WITH_STDLIB
|
||||
// IS_APPLICABLE: FALSE
|
||||
// PROBLEM: none
|
||||
|
||||
fun foo() {
|
||||
listOf(1,2,3).forEach {
|
||||
@@ -6369,8 +6369,6 @@ public abstract class K2IntentionTestGenerated extends AbstractK2IntentionTest {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.idea.base.psi.getParentLambdaLabelName
|
||||
import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.codeinsight.api.classic.intentions.SelfTargetingIntention
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.kotlin.psi.KtReturnExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
|
||||
class RemoveLabeledReturnInLambdaIntention : SelfTargetingIntention<KtReturnExpression>(
|
||||
KtReturnExpression::class.java,
|
||||
KotlinBundle.lazyMessage("remove.labeled.return.from.last.expression.in.a.lambda")
|
||||
), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtReturnExpression, caretOffset: Int): Boolean {
|
||||
val labelName = element.getLabelName() ?: return false
|
||||
val block = element.getStrictParentOfType<KtBlockExpression>() ?: return false
|
||||
if (block.statements.lastOrNull() != element) return false
|
||||
val callName = block.getParentLambdaLabelName() ?: return false
|
||||
if (labelName != callName) return false
|
||||
setTextGetter { KotlinBundle.message("remove.return.0", labelName) }
|
||||
return true
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtReturnExpression, editor: Editor?) {
|
||||
val returnedExpression = element.returnedExpression
|
||||
if (returnedExpression == null) {
|
||||
element.delete()
|
||||
} else {
|
||||
element.replace(returnedExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15665,54 +15665,6 @@ public abstract class K1IntentionTestGenerated extends AbstractK1IntentionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("testData/intentions/removeLabeledReturnInLambda")
|
||||
public static class RemoveLabeledReturnInLambda extends AbstractK1IntentionTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("labeledLambda.kt")
|
||||
public void testLabeledLambda() throws Exception {
|
||||
runTest("testData/intentions/removeLabeledReturnInLambda/labeledLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multipleBlocks.kt")
|
||||
public void testMultipleBlocks() throws Exception {
|
||||
runTest("testData/intentions/removeLabeledReturnInLambda/multipleBlocks.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("normal.kt")
|
||||
public void testNormal() throws Exception {
|
||||
runTest("testData/intentions/removeLabeledReturnInLambda/normal.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notInsideLabeled.kt")
|
||||
public void testNotInsideLabeled() throws Exception {
|
||||
runTest("testData/intentions/removeLabeledReturnInLambda/notInsideLabeled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notLabeled.kt")
|
||||
public void testNotLabeled() throws Exception {
|
||||
runTest("testData/intentions/removeLabeledReturnInLambda/notLabeled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notLastLine.kt")
|
||||
public void testNotLastLine() throws Exception {
|
||||
runTest("testData/intentions/removeLabeledReturnInLambda/notLastLine.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("outerLambda.kt")
|
||||
public void testOuterLambda() throws Exception {
|
||||
runTest("testData/intentions/removeLabeledReturnInLambda/outerLambda.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unit.kt")
|
||||
public void testUnit() throws Exception {
|
||||
runTest("testData/intentions/removeLabeledReturnInLambda/unit.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@TestMetadata("testData/intentions/removeRedundantCallsOfConversionMethods")
|
||||
public static class RemoveRedundantCallsOfConversionMethods extends AbstractK1IntentionTest {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
org.jetbrains.kotlin.idea.intentions.RemoveLabeledReturnInLambdaIntention
|
||||
@@ -784,13 +784,6 @@
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<language>kotlin</language>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.RemoveLabeledReturnInLambdaIntention</className>
|
||||
<bundleName>messages.KotlinBundle</bundleName>
|
||||
<categoryKey>group.names.kotlin</categoryKey>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<language>kotlin</language>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.AddLabeledReturnInLambdaIntention</className>
|
||||
|
||||
@@ -154,7 +154,6 @@ internal fun MutableTWorkspace.generateK2IntentionTests() {
|
||||
model("${idea}intentions/indentRawString", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/replaceAddWithPlusAssign", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/reconstructTypeInCastOrIs", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/removeLabeledReturnInLambda", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/convertParameterToReceiver", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/convertCollectionConstructorToFunction", pattern = pattern, isIgnored = true)
|
||||
model("${idea}intentions/replaceMapGetOrDefault", pattern = pattern, isIgnored = true)
|
||||
|
||||
Reference in New Issue
Block a user