From 45c3d74b4268f74a4b464bb494d8694e3df25f26 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 23 Sep 2015 21:39:37 +0300 Subject: [PATCH] KT-9284 Intention to convert to expression body doesn't work in particular case #KT-9284 Fixed --- .../ConvertToExpressionBodyIntention.kt | 21 +++++-------------- .../returnFromLambda.kt | 8 +++++++ .../returnFromLambda.kt.after | 6 ++++++ .../returnFromLambda2.kt | 8 +++++++ .../returnFromLambda2.kt.after | 6 ++++++ .../intentions/IntentionTestGenerated.java | 12 +++++++++++ 6 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt create mode 100644 idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt.after create mode 100644 idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt create mode 100644 idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToExpressionBodyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToExpressionBodyIntention.kt index 554b354d815..ee2fdb487d0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToExpressionBodyIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToExpressionBodyIntention.kt @@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor import org.jetbrains.kotlin.idea.core.CommentSaver import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.BindingContext @@ -36,8 +37,10 @@ public class ConvertToExpressionBodyIntention : JetSelfTargetingOffsetIndependen javaClass(), "Convert to expression body" ) { override fun isApplicableTo(element: JetDeclarationWithBody): Boolean { - val value = calcValue(element) - return value != null && !containsReturn(value) + val value = calcValue(element) ?: return false + return !value.anyDescendantOfType( + canGoInside = { it !is JetFunctionLiteral && it !is JetNamedFunction && it !is JetPropertyAccessor } + ) } override fun allowCaretInsideElement(element: PsiElement) = element !is JetDeclaration @@ -121,18 +124,4 @@ public class ConvertToExpressionBodyIntention : JetSelfTargetingOffsetIndependen } } } - - private fun containsReturn(element: PsiElement): Boolean { - if (element is JetReturnExpression) return true - //TODO: would be better to have some interface of declaration where return can be used - if (element is JetNamedFunction || element is JetPropertyAccessor) return false // can happen inside - - var child = element.getFirstChild() - while (child != null) { - if (containsReturn(child)) return true - child = child.getNextSibling() - } - - return false - } } diff --git a/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt b/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt new file mode 100644 index 00000000000..27e0ac735de --- /dev/null +++ b/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME + +public fun List.fn() : List { + return map { + if (it.isEmpty()) return@map "" + it + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt.after b/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt.after new file mode 100644 index 00000000000..6ec1b02ddd2 --- /dev/null +++ b/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +public fun List.fn() : List = map { + if (it.isEmpty()) return@map "" + it +} \ No newline at end of file diff --git a/idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt b/idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt new file mode 100644 index 00000000000..d7b74850628 --- /dev/null +++ b/idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME + +public fun List.fn() : List { + return map { + if (it.isEmpty()) return emptyList() + it + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt.after b/idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt.after new file mode 100644 index 00000000000..762b4b001b0 --- /dev/null +++ b/idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME + +public fun List.fn() : List = map { + if (it.isEmpty()) return emptyList() + it +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 45f693a54f5..50886c96e38 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -4180,6 +4180,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("returnFromLambda.kt") + public void testReturnFromLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt"); + doTest(fileName); + } + + @TestMetadata("returnFromLambda2.kt") + public void testReturnFromLambda2() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt"); + doTest(fileName); + } + @TestMetadata("returnWithNoValue.kt") public void testReturnWithNoValue() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/returnWithNoValue.kt");