Add quick-fix to "Unlabeled return inside lambda" inspection #KT-27007 Fixed

This commit is contained in:
Toshiaki Kameyama
2018-10-05 13:21:48 +09:00
committed by Mikhail Glukhikh
parent d7b885159e
commit 725cb88f41
7 changed files with 57 additions and 18 deletions
@@ -5,24 +5,35 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.IntentionWrapper
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.quickfix.ChangeToLabeledReturnFix
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtReturnExpression
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.returnExpressionVisitor
class UnlabeledReturnInsideLambdaInspection : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
returnExpressionVisitor(fun(returnExpression: KtReturnExpression) {
if (returnExpression.labelQualifier != null) return
if (returnExpression.getParentOfType<KtLambdaExpression>(true, KtNamedFunction::class.java) == null) return
val lambda = returnExpression.getParentOfType<KtLambdaExpression>(true, KtNamedFunction::class.java) ?: return
val parentFunction = lambda.getStrictParentOfType<KtNamedFunction>() ?: return
if (returnExpression.analyze().diagnostics.forElement(returnExpression).any { it.severity == Severity.ERROR }) return
holder.registerProblem(
returnExpression,
returnExpression.returnKeyword,
"Unlabeled return inside lambda",
ProblemHighlightType.GENERIC_ERROR_OR_WARNING
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
IntentionWrapper(
ChangeToLabeledReturnFix(returnExpression, labeledReturn = "return@${parentFunction.name}"),
returnExpression.containingFile
)
)
})
}
@@ -1,7 +1,9 @@
// PROBLEM: none
// WITH_RUNTIME
fun test() {
listOf(1).forEach {
if (it == 10) <caret>return@forEach
inline fun foo(f: () -> Unit) {}
fun test(): Int {
foo {
<caret>return@test 0
}
return 1
}
@@ -0,0 +1,10 @@
// PROBLEM: none
// DISABLE-ERRORS
fun foo(f: () -> Unit) {}
fun test(): Int {
foo {
return<caret> 0
}
return 1
}
@@ -1,7 +1,8 @@
// FIX: none
// WITH_RUNTIME
fun test() {
listOf(1).forEach {
if (it == 10) <caret>return
inline fun foo(f: () -> Unit) {}
fun test(): Int {
foo {
return<caret> 0
}
return 1
}
@@ -0,0 +1,8 @@
inline fun foo(f: () -> Unit) {}
fun test(): Int {
foo {
return@test 0
}
return 1
}
@@ -1,9 +1,11 @@
// PROBLEM: none
// WITH_RUNTIME
fun test() {
listOf(1).forEach {
fun foo() {
if (it == 10) <caret>return
inline fun foo(f: () -> Unit) {}
fun test(): Int {
foo {
fun bar() {
return<caret>
}
}
}
return 1
}
@@ -6041,6 +6041,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
runTest("idea/testData/inspectionsLocal/unlabeledReturnInsideLambda/labeledReturn.kt");
}
@TestMetadata("notInlineFunction.kt")
public void testNotInlineFunction() throws Exception {
runTest("idea/testData/inspectionsLocal/unlabeledReturnInsideLambda/notInlineFunction.kt");
}
@TestMetadata("return.kt")
public void testReturn() throws Exception {
runTest("idea/testData/inspectionsLocal/unlabeledReturnInsideLambda/return.kt");