Return back intention "convert to expression body" #KT-19759 Fixed
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index f01a697..9ca1c21 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -867,6 +867,11 @@
     </intentionAction>
 
     <intentionAction>
+      <className>org.jetbrains.kotlin.idea.intentions.ConvertToExpressionBodyIntention</className>
+      <category>Kotlin</category>
+    </intentionAction>
+
+    <intentionAction>
       <className>org.jetbrains.kotlin.idea.intentions.ConvertToBlockBodyIntention</className>
       <category>Kotlin</category>
     </intentionAction>
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToExpressionBodyIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToExpressionBodyIntention.kt
new file mode 100644
index 0000000..9dee763
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertToExpressionBodyIntention.kt
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright 2010-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.intentions
+
+import com.intellij.openapi.editor.Editor
+import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.idea.caches.resolve.analyze
+import org.jetbrains.kotlin.idea.core.canOmitDeclaredType
+import org.jetbrains.kotlin.idea.core.replaced
+import org.jetbrains.kotlin.idea.core.setType
+import org.jetbrains.kotlin.idea.util.CommentSaver
+import org.jetbrains.kotlin.lexer.KtTokens
+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
+
+class ConvertToExpressionBodyIntention(
+        val convertEmptyToUnit: Boolean = true
+) : SelfTargetingOffsetIndependentIntention<KtDeclarationWithBody>(
+        KtDeclarationWithBody::class.java, "Convert to expression body"
+) {
+    override fun isApplicableTo(element: KtDeclarationWithBody): Boolean {
+        if (element is KtConstructor<*>) return false
+        val value = calcValue(element) ?: return false
+        return !value.anyDescendantOfType<KtReturnExpression>(
+                canGoInside = { it !is KtFunctionLiteral && it !is KtNamedFunction && it !is KtPropertyAccessor }
+        )
+    }
+
+    override fun allowCaretInsideElement(element: PsiElement) = element !is KtDeclaration
+
+    override fun applyTo(element: KtDeclarationWithBody, editor: Editor?) {
+        applyTo(element) {
+            val typeRef = it.typeReference!!
+            val colon = it.colon!!
+            editor?.apply {
+                selectionModel.setSelection(colon.startOffset, typeRef.endOffset)
+                caretModel.moveToOffset(typeRef.endOffset)
+            }
+        }
+    }
+
+    fun applyTo(declaration: KtDeclarationWithBody, canDeleteTypeRef: Boolean) {
+        val deleteTypeHandler: (KtCallableDeclaration) -> Unit = {
+            it.deleteChildRange(it.colon!!, it.typeReference!!)
+        }
+        applyTo(declaration, deleteTypeHandler.takeIf { canDeleteTypeRef })
+    }
+
+    private fun applyTo(declaration: KtDeclarationWithBody, deleteTypeHandler: ((KtCallableDeclaration) -> Unit)?) {
+        val block = declaration.blockExpression() ?: return
+        val value = calcValue(block)!!
+
+        if (!declaration.hasDeclaredReturnType() && declaration is KtNamedFunction && block.statements.isNotEmpty()) {
+            val valueType = value.analyze().getType(value)
+            if (valueType == null || !KotlinBuiltIns.isUnit(valueType)) {
+                declaration.setType(KotlinBuiltIns.FQ_NAMES.unit.asString(), shortenReferences = true)
+            }
+        }
+
+        val body = declaration.bodyExpression!!
+
+        val commentSaver = CommentSaver(body)
+
+        declaration.addBefore(KtPsiFactory(declaration).createEQ(), body)
+        val newBody = body.replaced(value)
+
+        commentSaver.restore(newBody)
+
+        if (deleteTypeHandler != null && declaration is KtCallableDeclaration) {
+            if (declaration.hasDeclaredReturnType() && declaration.canOmitDeclaredType(newBody, canChangeTypeToSubtype = true)) {
+                deleteTypeHandler(declaration)
+            }
+        }
+    }
+
+    private fun KtDeclarationWithBody.blockExpression() = when (this) {
+        is KtFunctionLiteral -> null
+        else -> {
+            val body = bodyExpression
+            if (!hasBlockBody() || body !is KtBlockExpression) null else body
+        }
+    }
+
+    private fun calcValue(declaration: KtDeclarationWithBody): KtExpression? {
+        val body = declaration.blockExpression() ?: return null
+        return calcValue(body)
+    }
+
+    private fun calcValue(body: KtBlockExpression): KtExpression? {
+        val bodyStatements = body.statements
+        if (bodyStatements.isEmpty()) {
+            return if (convertEmptyToUnit) KtPsiFactory(body).createExpression("Unit") else null
+        }
+        val statement = bodyStatements.singleOrNull() ?: return null
+        when (statement) {
+            is KtReturnExpression -> {
+                return statement.returnedExpression
+            }
+
+            //TODO: IMO this is not good code, there should be a way to detect that JetExpression does not have value
+            is KtDeclaration, is KtLoopExpression -> return null // is JetExpression but does not have value
+
+            else -> {
+                if (statement is KtBinaryExpression && statement.operationToken in KtTokens.ALL_ASSIGNMENTS) return null // assignment does not have value
+
+                val context = statement.analyze()
+                val expressionType = context.getType(statement) ?: return null
+                val isUnit = KotlinBuiltIns.isUnit(expressionType)
+                if (!isUnit && !KotlinBuiltIns.isNothing(expressionType)) return null
+                if (isUnit) {
+                    if (statement.hasResultingIfWithoutElse()) {
+                        return null
+                    }
+                    val resultingWhens = statement.resultingWhens()
+                    if (resultingWhens.any { it.elseExpression == null && context.get(BindingContext.EXHAUSTIVE_WHEN, it) != true }) {
+                        return null
+                    }
+                }
+                return statement
+            }
+        }
+    }
+}
diff --git a/idea/testData/intentions/convertToExpressionBody/.intention b/idea/testData/intentions/convertToExpressionBody/.intention
new file mode 100644
index 0000000..da16192
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/.intention
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.intentions.ConvertToExpressionBodyIntention
diff --git a/idea/testData/intentions/convertToExpressionBody/anonymousObjectExpression.kt b/idea/testData/intentions/convertToExpressionBody/anonymousObjectExpression.kt
new file mode 100644
index 0000000..9bb2981
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/anonymousObjectExpression.kt
@@ -0,0 +1,11 @@
+interface I {
+    fun foo(): String
+}
+
+fun bar(): I {
+    <caret>return object: I {
+        override fun foo(): String {
+            return "a"
+        }
+    }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/anonymousObjectExpression.kt.after b/idea/testData/intentions/convertToExpressionBody/anonymousObjectExpression.kt.after
new file mode 100644
index 0000000..2d75ef4
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/anonymousObjectExpression.kt.after
@@ -0,0 +1,9 @@
+interface I {
+    fun foo(): String
+}
+
+fun bar()<selection>: I</selection> = object: I {
+    override fun foo(): String {
+        return "a"
+    }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/assignPlus.kt b/idea/testData/intentions/convertToExpressionBody/assignPlus.kt
new file mode 100644
index 0000000..1a835b6
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/assignPlus.kt
@@ -0,0 +1,7 @@
+// IS_APPLICABLE: false
+
+var x = 0
+
+fun <caret>foo() {
+    x += 1
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/assignment.kt b/idea/testData/intentions/convertToExpressionBody/assignment.kt
new file mode 100644
index 0000000..a39404c
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/assignment.kt
@@ -0,0 +1,8 @@
+// IS_APPLICABLE: false
+
+var a = 1
+var b = 2
+
+fun foo() {
+    <caret>a = b
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/constructorWithEmptyBody.kt b/idea/testData/intentions/convertToExpressionBody/constructorWithEmptyBody.kt
new file mode 100644
index 0000000..590744d
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/constructorWithEmptyBody.kt
@@ -0,0 +1,5 @@
+// IS_APPLICABLE: false
+
+class C {
+    constructor()<caret> {}
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/declaration.kt b/idea/testData/intentions/convertToExpressionBody/declaration.kt
new file mode 100644
index 0000000..564c3d5
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/declaration.kt
@@ -0,0 +1,5 @@
+// IS_APPLICABLE: false
+
+fun foo() {
+    <caret>val v = 1
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/elvisIfElseUnit.kt b/idea/testData/intentions/convertToExpressionBody/elvisIfElseUnit.kt
new file mode 100644
index 0000000..e4c6531
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/elvisIfElseUnit.kt
@@ -0,0 +1,9 @@
+// IS_APPLICABLE: true
+
+fun nullable() {}
+
+fun bar() {}
+
+fun foo(f: Boolean) {
+    <caret>nullable() ?: if (f) bar() else bar()
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/elvisIfElseUnit.kt.after b/idea/testData/intentions/convertToExpressionBody/elvisIfElseUnit.kt.after
new file mode 100644
index 0000000..4666e3e
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/elvisIfElseUnit.kt.after
@@ -0,0 +1,7 @@
+// IS_APPLICABLE: true
+
+fun nullable() {}
+
+fun bar() {}
+
+fun foo(f: Boolean) = nullable() ?: if (f) bar() else bar()
diff --git a/idea/testData/intentions/convertToExpressionBody/elvisIfUnit.kt b/idea/testData/intentions/convertToExpressionBody/elvisIfUnit.kt
new file mode 100644
index 0000000..0fd4a72
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/elvisIfUnit.kt
@@ -0,0 +1,9 @@
+// IS_APPLICABLE: false
+
+fun nullable() {}
+
+fun bar() {}
+
+fun foo(f: Boolean) {
+    <caret>nullable() ?: if (f) bar()
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/elvisWhenUnitNonExhaustive.kt b/idea/testData/intentions/convertToExpressionBody/elvisWhenUnitNonExhaustive.kt
new file mode 100644
index 0000000..5f66936
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/elvisWhenUnitNonExhaustive.kt
@@ -0,0 +1,10 @@
+// IS_APPLICABLE: false
+
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(access: AccessMode) {
+    <caret>println("result") ?: when (access) {
+        AccessMode.READ -> println("read")
+        AccessMode.WRITE -> println("write")
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/emptyList.kt b/idea/testData/intentions/convertToExpressionBody/emptyList.kt
new file mode 100644
index 0000000..f133ee5
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/emptyList.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo(): List<String> {
+    ret<caret>urn emptyList()
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/emptyList.kt.after b/idea/testData/intentions/convertToExpressionBody/emptyList.kt.after
new file mode 100644
index 0000000..2d22b9e
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/emptyList.kt.after
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+fun foo(): List<String> = emptyList()
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/expressionWithReturns1.kt b/idea/testData/intentions/convertToExpressionBody/expressionWithReturns1.kt
new file mode 100644
index 0000000..7b20bdb
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/expressionWithReturns1.kt
@@ -0,0 +1,7 @@
+// IS_APPLICABLE: false
+
+fun foo(p: Boolean): String {
+    <caret>return bar() ?: return "a"
+}
+
+fun bar(): String? = null
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/expressionWithReturns2.kt b/idea/testData/intentions/convertToExpressionBody/expressionWithReturns2.kt
new file mode 100644
index 0000000..81d1280
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/expressionWithReturns2.kt
@@ -0,0 +1,10 @@
+// IS_APPLICABLE: false
+
+fun foo(p: Boolean): String {
+    if (p) {
+        <caret>return "abc"
+    }
+    else {
+        return "def"
+    }
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody.kt b/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody.kt
new file mode 100644
index 0000000..bb58a89
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody.kt
@@ -0,0 +1,2 @@
+fun <caret>foo() {
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody.kt.after b/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody.kt.after
new file mode 100644
index 0000000..44ce3c5
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody.kt.after
@@ -0,0 +1 @@
+fun foo() = Unit
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody2.kt b/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody2.kt
new file mode 100644
index 0000000..05a1965
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody2.kt
@@ -0,0 +1,2 @@
+fun <caret>foo(): Unit {
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody2.kt.after b/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody2.kt.after
new file mode 100644
index 0000000..b8b8e1a
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithEmptyBody2.kt.after
@@ -0,0 +1 @@
+fun foo(): Unit = Unit
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithImplicitUnitTypeWithThrow.kt b/idea/testData/intentions/convertToExpressionBody/funWithImplicitUnitTypeWithThrow.kt
new file mode 100644
index 0000000..bb0d22c
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithImplicitUnitTypeWithThrow.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo() {
+    <caret>throw UnsupportedOperationException()
+}
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithImplicitUnitTypeWithThrow.kt.after b/idea/testData/intentions/convertToExpressionBody/funWithImplicitUnitTypeWithThrow.kt.after
new file mode 100644
index 0000000..c660891
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithImplicitUnitTypeWithThrow.kt.after
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+fun foo()<selection>: Unit</selection> = throw UnsupportedOperationException()
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithNoBlock.kt b/idea/testData/intentions/convertToExpressionBody/funWithNoBlock.kt
new file mode 100644
index 0000000..416bf97
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithNoBlock.kt
@@ -0,0 +1,3 @@
+// IS_APPLICABLE: false
+
+fun foo() = <caret>"abc"
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithNothingType.kt b/idea/testData/intentions/convertToExpressionBody/funWithNothingType.kt
new file mode 100644
index 0000000..ff08581
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithNothingType.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo(): Nothing {
+    <caret>throw UnsupportedOperationException()
+}
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithNothingType.kt.after b/idea/testData/intentions/convertToExpressionBody/funWithNothingType.kt.after
new file mode 100644
index 0000000..1907e83
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithNothingType.kt.after
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+fun foo()<selection>: Nothing</selection> = throw UnsupportedOperationException()
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithReturn.kt b/idea/testData/intentions/convertToExpressionBody/funWithReturn.kt
new file mode 100644
index 0000000..90fb86d
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithReturn.kt
@@ -0,0 +1,3 @@
+fun foo(): String {
+    <caret>return "abc"
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithReturn.kt.after b/idea/testData/intentions/convertToExpressionBody/funWithReturn.kt.after
new file mode 100644
index 0000000..f58b600
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithReturn.kt.after
@@ -0,0 +1 @@
+fun foo()<selection>: String</selection> = "abc"
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithUnitType.kt b/idea/testData/intentions/convertToExpressionBody/funWithUnitType.kt
new file mode 100644
index 0000000..3512548
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithUnitType.kt
@@ -0,0 +1,5 @@
+fun foo() {
+    <caret>bar()
+}
+
+fun bar() { }
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithUnitType.kt.after b/idea/testData/intentions/convertToExpressionBody/funWithUnitType.kt.after
new file mode 100644
index 0000000..c77b79b
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithUnitType.kt.after
@@ -0,0 +1,3 @@
+fun foo() = bar()
+
+fun bar() { }
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithUnitType2.kt b/idea/testData/intentions/convertToExpressionBody/funWithUnitType2.kt
new file mode 100644
index 0000000..ffbebee
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithUnitType2.kt
@@ -0,0 +1,7 @@
+// IS_APPLICABLE: false
+
+fun foo() {
+    <caret>bar()
+}
+
+fun bar(): String = "abc"
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithUnitTypeWithThrow.kt b/idea/testData/intentions/convertToExpressionBody/funWithUnitTypeWithThrow.kt
new file mode 100644
index 0000000..b0f8976
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithUnitTypeWithThrow.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+fun foo(): Unit {
+    <caret>throw UnsupportedOperationException()
+}
diff --git a/idea/testData/intentions/convertToExpressionBody/funWithUnitTypeWithThrow.kt.after b/idea/testData/intentions/convertToExpressionBody/funWithUnitTypeWithThrow.kt.after
new file mode 100644
index 0000000..c660891
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/funWithUnitTypeWithThrow.kt.after
@@ -0,0 +1,3 @@
+// WITH_RUNTIME
+
+fun foo()<selection>: Unit</selection> = throw UnsupportedOperationException()
diff --git a/idea/testData/intentions/convertToExpressionBody/functionLiteral.kt b/idea/testData/intentions/convertToExpressionBody/functionLiteral.kt
new file mode 100644
index 0000000..c73634d
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/functionLiteral.kt
@@ -0,0 +1,9 @@
+// IS_APPLICABLE: false
+
+fun foo(handler: () -> Unit) { }
+
+fun bar() {
+    foo { <caret>zoo() }
+}
+
+fun zoo(){}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/getWithReturn.kt b/idea/testData/intentions/convertToExpressionBody/getWithReturn.kt
new file mode 100644
index 0000000..533b47e
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/getWithReturn.kt
@@ -0,0 +1,4 @@
+val foo: String
+    get() {
+        <caret>return "abc"
+    }
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/getWithReturn.kt.after b/idea/testData/intentions/convertToExpressionBody/getWithReturn.kt.after
new file mode 100644
index 0000000..5b4d520
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/getWithReturn.kt.after
@@ -0,0 +1,2 @@
+val foo: String
+    get() = "abc"
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/ifElseUnit.kt b/idea/testData/intentions/convertToExpressionBody/ifElseUnit.kt
new file mode 100644
index 0000000..d85f7c0
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/ifElseUnit.kt
@@ -0,0 +1,7 @@
+// IS_APPLICABLE: true
+
+fun bar() {}
+
+fun foo(f: Boolean) {
+    <caret>if (f) bar() else bar()
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/ifElseUnit.kt.after b/idea/testData/intentions/convertToExpressionBody/ifElseUnit.kt.after
new file mode 100644
index 0000000..c0f5a3e
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/ifElseUnit.kt.after
@@ -0,0 +1,5 @@
+// IS_APPLICABLE: true
+
+fun bar() {}
+
+fun foo(f: Boolean) = if (f) bar() else bar()
diff --git a/idea/testData/intentions/convertToExpressionBody/ifUnit.kt b/idea/testData/intentions/convertToExpressionBody/ifUnit.kt
new file mode 100644
index 0000000..09b9ab3
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/ifUnit.kt
@@ -0,0 +1,7 @@
+// IS_APPLICABLE: false
+
+fun bar() {}
+
+fun foo(f: Boolean) {
+    <caret>if (f) bar()
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/ifWhenUnitExhaustive.kt b/idea/testData/intentions/convertToExpressionBody/ifWhenUnitExhaustive.kt
new file mode 100644
index 0000000..46fec04
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/ifWhenUnitExhaustive.kt
@@ -0,0 +1,19 @@
+// IS_APPLICABLE: true
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(mode: Boolean, access: AccessMode) {
+    <caret>if (mode) {
+        when (access) {
+            AccessMode.READ -> println("read")
+            AccessMode.WRITE -> println("write")
+            AccessMode.RW -> println("both")
+        }
+    }
+    else {
+        when (access) {
+            AccessMode.READ -> println("noread")
+            AccessMode.WRITE -> println("nowrite")
+            AccessMode.RW -> println("no both")
+        }
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/ifWhenUnitExhaustive.kt.after b/idea/testData/intentions/convertToExpressionBody/ifWhenUnitExhaustive.kt.after
new file mode 100644
index 0000000..1142ade
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/ifWhenUnitExhaustive.kt.after
@@ -0,0 +1,17 @@
+// IS_APPLICABLE: true
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(mode: Boolean, access: AccessMode) = if (mode) {
+    when (access) {
+        AccessMode.READ -> println("read")
+        AccessMode.WRITE -> println("write")
+        AccessMode.RW -> println("both")
+    }
+}
+else {
+    when (access) {
+        AccessMode.READ -> println("noread")
+        AccessMode.WRITE -> println("nowrite")
+        AccessMode.RW -> println("no both")
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/ifWhenUnitNonExhaustive.kt b/idea/testData/intentions/convertToExpressionBody/ifWhenUnitNonExhaustive.kt
new file mode 100644
index 0000000..46528b4
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/ifWhenUnitNonExhaustive.kt
@@ -0,0 +1,19 @@
+// IS_APPLICABLE: false
+
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(mode: Boolean, access: AccessMode) {
+    <caret>if (mode) {
+        when (access) {
+            AccessMode.READ -> println("read")
+            AccessMode.WRITE -> println("write")
+        }
+    }
+    else {
+        when (access) {
+            AccessMode.READ -> println("noread")
+            AccessMode.WRITE -> println("nowrite")
+            AccessMode.RW -> println("no both")
+        }
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/lambdaIfUnit.kt b/idea/testData/intentions/convertToExpressionBody/lambdaIfUnit.kt
new file mode 100644
index 0000000..9b0ee79
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/lambdaIfUnit.kt
@@ -0,0 +1,12 @@
+// IS_APPLICABLE: true
+
+fun <T> run(f: () -> T) = f()
+fun whenExpr(flag: Boolean) {
+    <caret>run {
+        println("run")
+        if (flag) {
+            println("flag")
+        }
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/lambdaIfUnit.kt.after b/idea/testData/intentions/convertToExpressionBody/lambdaIfUnit.kt.after
new file mode 100644
index 0000000..b09c417
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/lambdaIfUnit.kt.after
@@ -0,0 +1,10 @@
+// IS_APPLICABLE: true
+
+fun <T> run(f: () -> T) = f()
+fun whenExpr(flag: Boolean) = run {
+    println("run")
+    if (flag) {
+        println("flag")
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/lambdaWhenUnitNonExhaustive.kt b/idea/testData/intentions/convertToExpressionBody/lambdaWhenUnitNonExhaustive.kt
new file mode 100644
index 0000000..4a9c7a2
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/lambdaWhenUnitNonExhaustive.kt
@@ -0,0 +1,13 @@
+// IS_APPLICABLE: true
+enum class AccessMode { READ, WRITE, RW }
+fun <T> run(f: () -> T) = f()
+fun whenExpr(access: AccessMode) {
+    <caret>run {
+        println("run")
+        when (access) {
+            AccessMode.READ -> println("read")
+            AccessMode.WRITE -> println("write")
+        }
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/lambdaWhenUnitNonExhaustive.kt.after b/idea/testData/intentions/convertToExpressionBody/lambdaWhenUnitNonExhaustive.kt.after
new file mode 100644
index 0000000..aa37ea5
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/lambdaWhenUnitNonExhaustive.kt.after
@@ -0,0 +1,11 @@
+// IS_APPLICABLE: true
+enum class AccessMode { READ, WRITE, RW }
+fun <T> run(f: () -> T) = f()
+fun whenExpr(access: AccessMode) = run {
+    println("run")
+    when (access) {
+        AccessMode.READ -> println("read")
+        AccessMode.WRITE -> println("write")
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/multipleStatements.kt b/idea/testData/intentions/convertToExpressionBody/multipleStatements.kt
new file mode 100644
index 0000000..796fcdc
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/multipleStatements.kt
@@ -0,0 +1,6 @@
+// IS_APPLICABLE: false
+
+fun foo(): String {
+    val v = 1
+    <caret>return "abc"
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/overridePublicFun.kt b/idea/testData/intentions/convertToExpressionBody/overridePublicFun.kt
new file mode 100644
index 0000000..724b389
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/overridePublicFun.kt
@@ -0,0 +1,9 @@
+open class A {
+    public open fun foo(): String = ""
+}
+
+class B : A() {
+    public override fun foo(): String {
+        <caret>return "abc"
+    }
+}
diff --git a/idea/testData/intentions/convertToExpressionBody/overridePublicFun.kt.after b/idea/testData/intentions/convertToExpressionBody/overridePublicFun.kt.after
new file mode 100644
index 0000000..d355ef3
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/overridePublicFun.kt.after
@@ -0,0 +1,7 @@
+open class A {
+    public open fun foo(): String = ""
+}
+
+class B : A() {
+    public override fun foo()<selection>: String</selection> = "abc"
+}
diff --git a/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt b/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt
new file mode 100644
index 0000000..27e0ac7
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt
@@ -0,0 +1,8 @@
+// WITH_RUNTIME
+
+public fun List<String>.fn() : List<String> {
+    <caret>return map {
+        if (it.isEmpty()) return@map "<empty>"
+        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 0000000..6ec1b02
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt.after
@@ -0,0 +1,6 @@
+// WITH_RUNTIME
+
+public fun List<String>.fn() <selection>: List<String></selection><caret> = map {
+    if (it.isEmpty()) return@map "<empty>"
+    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 0000000..d7b7485
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt
@@ -0,0 +1,8 @@
+// WITH_RUNTIME
+
+public fun List<String>.fn() : List<String> {
+    <caret>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 0000000..762b4b0
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt.after
@@ -0,0 +1,6 @@
+// WITH_RUNTIME
+
+public fun List<String>.fn() : List<String> = map {
+    if (it.isEmpty()) return emptyList()
+    it
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/returnWithNoValue.kt b/idea/testData/intentions/convertToExpressionBody/returnWithNoValue.kt
new file mode 100644
index 0000000..cfca0c5
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/returnWithNoValue.kt
@@ -0,0 +1,5 @@
+// IS_APPLICABLE: false
+
+fun foo() {
+    <caret>return
+}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/whenIfUnitExhaustive.kt b/idea/testData/intentions/convertToExpressionBody/whenIfUnitExhaustive.kt
new file mode 100644
index 0000000..4e9d382
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/whenIfUnitExhaustive.kt
@@ -0,0 +1,10 @@
+// IS_APPLICABLE: true
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(mode: Boolean, access: AccessMode) {
+    <caret>when (access) {
+        AccessMode.READ -> if (mode) println("read") else println("noread")
+        AccessMode.WRITE -> if (mode) println("write") else println("nowrite")
+        AccessMode.RW -> if (mode) println("both") else println("no both")
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/whenIfUnitExhaustive.kt.after b/idea/testData/intentions/convertToExpressionBody/whenIfUnitExhaustive.kt.after
new file mode 100644
index 0000000..774bec4
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/whenIfUnitExhaustive.kt.after
@@ -0,0 +1,8 @@
+// IS_APPLICABLE: true
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(mode: Boolean, access: AccessMode) = when (access) {
+    AccessMode.READ -> if (mode) println("read") else println("noread")
+    AccessMode.WRITE -> if (mode) println("write") else println("nowrite")
+    AccessMode.RW -> if (mode) println("both") else println("no both")
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/whenIfUnitNonExhaustive.kt b/idea/testData/intentions/convertToExpressionBody/whenIfUnitNonExhaustive.kt
new file mode 100644
index 0000000..03127e7
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/whenIfUnitNonExhaustive.kt
@@ -0,0 +1,11 @@
+// IS_APPLICABLE: false
+
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(mode: Boolean, access: AccessMode) {
+    <caret>when (access) {
+        AccessMode.READ -> if (mode) println("read") else println("noread")
+        AccessMode.WRITE -> if (mode) println("write")
+        AccessMode.RW -> if (mode) println("both") else println("no both")
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/whenUnitExhaustive.kt b/idea/testData/intentions/convertToExpressionBody/whenUnitExhaustive.kt
new file mode 100644
index 0000000..e159d94
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/whenUnitExhaustive.kt
@@ -0,0 +1,9 @@
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(access: AccessMode) {
+    <caret>when (access) {
+        AccessMode.READ -> println("read")
+        AccessMode.WRITE -> println("write")
+        AccessMode.RW -> println("rw")
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/whenUnitExhaustive.kt.after b/idea/testData/intentions/convertToExpressionBody/whenUnitExhaustive.kt.after
new file mode 100644
index 0000000..41642dd
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/whenUnitExhaustive.kt.after
@@ -0,0 +1,7 @@
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(access: AccessMode) = when (access) {
+    AccessMode.READ -> println("read")
+    AccessMode.WRITE -> println("write")
+    AccessMode.RW -> println("rw")
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/whenUnitNonExhaustive.kt b/idea/testData/intentions/convertToExpressionBody/whenUnitNonExhaustive.kt
new file mode 100644
index 0000000..8f795c4
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/whenUnitNonExhaustive.kt
@@ -0,0 +1,10 @@
+// IS_APPLICABLE: false
+
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(access: AccessMode) {
+    <caret>when (access) {
+        AccessMode.READ -> println("read")
+        AccessMode.WRITE -> println("write")
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/whenUnitWithElse.kt b/idea/testData/intentions/convertToExpressionBody/whenUnitWithElse.kt
new file mode 100644
index 0000000..9029e25
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/whenUnitWithElse.kt
@@ -0,0 +1,9 @@
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(access: AccessMode) {
+    <caret>when (access) {
+        AccessMode.READ -> println("read")
+        AccessMode.WRITE -> println("write")
+        else -> println("else")
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/whenUnitWithElse.kt.after b/idea/testData/intentions/convertToExpressionBody/whenUnitWithElse.kt.after
new file mode 100644
index 0000000..eb7cb5e
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/whenUnitWithElse.kt.after
@@ -0,0 +1,7 @@
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(access: AccessMode) = when (access) {
+    AccessMode.READ -> println("read")
+    AccessMode.WRITE -> println("write")
+    else -> println("else")
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/whenWhenNonExhaustive.kt b/idea/testData/intentions/convertToExpressionBody/whenWhenNonExhaustive.kt
new file mode 100644
index 0000000..ad5790a
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/whenWhenNonExhaustive.kt
@@ -0,0 +1,19 @@
+// IS_APPLICABLE: false
+
+enum class AccessMode { READ, WRITE, RW }
+fun whenExpr(mode: Boolean, access: AccessMode) {
+    <caret>when (access) {
+        AccessMode.READ -> when (mode) {
+            true -> println("read")
+            false -> println("noread")
+        }
+        AccessMode.WRITE -> when (mode) {
+            true -> println("write")
+        }
+        AccessMode.RW -> when (mode) {
+            true -> println("both")
+            else -> println("no both")
+        }
+    }
+}
+fun println(s: String) {}
\ No newline at end of file
diff --git a/idea/testData/intentions/convertToExpressionBody/while.kt b/idea/testData/intentions/convertToExpressionBody/while.kt
new file mode 100644
index 0000000..0743f79
--- /dev/null
+++ b/idea/testData/intentions/convertToExpressionBody/while.kt
@@ -0,0 +1,5 @@
+// IS_APPLICABLE: false
+
+fun foo(p: Boolean): String {
+    <caret>while(true) { }
+}
\ No newline at end of file
diff --git a/idea/testData/quickfix/addInline/local.kt b/idea/testData/quickfix/addInline/local.kt
index 4947f86..ae3dcf2 100644
--- a/idea/testData/quickfix/addInline/local.kt
+++ b/idea/testData/quickfix/addInline/local.kt
@@ -1,4 +1,5 @@
 // "Add 'inline' to function 'foo'" "false"
+// ACTION: Convert to expression body
 // ERROR: Modifier 'crossinline' is allowed only for function parameters of an inline function
 
 fun bar() {
diff --git a/idea/testData/quickfix/addStarProjections/cast/changeFunctionalToStarProjection.kt b/idea/testData/quickfix/addStarProjections/cast/changeFunctionalToStarProjection.kt
index d175b67..c10527f 100644
--- a/idea/testData/quickfix/addStarProjections/cast/changeFunctionalToStarProjection.kt
+++ b/idea/testData/quickfix/addStarProjections/cast/changeFunctionalToStarProjection.kt
@@ -1,4 +1,5 @@
 // "class org.jetbrains.kotlin.idea.quickfix.ChangeToStarProjectionFix" "false"
+// ACTION: Convert to expression body
 
 class Constructor<out T>(val x: T)
 
diff --git a/idea/testData/quickfix/addStarProjections/cast/uncheckedCastOnTypeParameter.kt b/idea/testData/quickfix/addStarProjections/cast/uncheckedCastOnTypeParameter.kt
index 8ba0863..b3fc00c 100644
--- a/idea/testData/quickfix/addStarProjections/cast/uncheckedCastOnTypeParameter.kt
+++ b/idea/testData/quickfix/addStarProjections/cast/uncheckedCastOnTypeParameter.kt
@@ -1,4 +1,5 @@
 // "class org.jetbrains.kotlin.idea.quickfix.ChangeToStarProjectionFix" "false"
+// ACTION: Convert to expression body
 fun <T> get(column: String, map: Map<String, Any>): T {
     return map[column] as <caret>T
 }
diff --git a/idea/testData/quickfix/autoImports/mismatchingArgs/checkArgumentTypes.test b/idea/testData/quickfix/autoImports/mismatchingArgs/checkArgumentTypes.test
index 90de355..987a89a 100644
--- a/idea/testData/quickfix/autoImports/mismatchingArgs/checkArgumentTypes.test
+++ b/idea/testData/quickfix/autoImports/mismatchingArgs/checkArgumentTypes.test
@@ -2,6 +2,7 @@
 // "Import" "false"
 // ERROR: Too many arguments for public final fun foo(): Unit defined in main.X
 // ACTION: Add parameter to function 'foo'
+// ACTION: Convert to expression body
 // ACTION: Create extension function 'X.foo'
 // ACTION: Create member function 'X.foo'
 
diff --git a/idea/testData/quickfix/autoImports/mismatchingArgs/extensionWrongReceiver.test b/idea/testData/quickfix/autoImports/mismatchingArgs/extensionWrongReceiver.test
index 27ec8a2..0d1e45c 100644
--- a/idea/testData/quickfix/autoImports/mismatchingArgs/extensionWrongReceiver.test
+++ b/idea/testData/quickfix/autoImports/mismatchingArgs/extensionWrongReceiver.test
@@ -2,6 +2,7 @@
 // "Import" "false"
 // ERROR: Too many arguments for public final fun foo(): Unit defined in main.X
 // ACTION: Add parameter to function 'foo'
+// ACTION: Convert to expression body
 // ACTION: Create extension function 'X.foo'
 // ACTION: Create member function 'X.foo'
 
diff --git a/idea/testData/quickfix/autoImports/mismatchingArgs/notForIncompleteCall.test b/idea/testData/quickfix/autoImports/mismatchingArgs/notForIncompleteCall.test
index 2f36f99..369d348 100644
--- a/idea/testData/quickfix/autoImports/mismatchingArgs/notForIncompleteCall.test
+++ b/idea/testData/quickfix/autoImports/mismatchingArgs/notForIncompleteCall.test
@@ -3,6 +3,7 @@
 // ERROR: Type mismatch: inferred type is Int but String was expected
 // ACTION: Add 'toString()' call
 // ACTION: Change parameter 'p' type of function 'main.X.foo' to 'Int'
+// ACTION: Convert to expression body
 // ACTION: Create function 'foo'
 
 package main
diff --git a/idea/testData/quickfix/autoImports/mismatchingArgs/topLevelFun_notWithReceiver.test b/idea/testData/quickfix/autoImports/mismatchingArgs/topLevelFun_notWithReceiver.test
index 15a2e7b..57db183 100644
--- a/idea/testData/quickfix/autoImports/mismatchingArgs/topLevelFun_notWithReceiver.test
+++ b/idea/testData/quickfix/autoImports/mismatchingArgs/topLevelFun_notWithReceiver.test
@@ -2,6 +2,7 @@
 // "Import" "false"
 // ERROR: Too many arguments for public final fun foo(): Unit defined in main.X
 // ACTION: Add parameter to function 'foo'
+// ACTION: Convert to expression body
 // ACTION: Create extension function 'X.foo'
 // ACTION: Create member function 'X.foo'
 
diff --git a/idea/testData/quickfix/autoImports/noImportInterfaceRefAsConstructor.after.kt b/idea/testData/quickfix/autoImports/noImportInterfaceRefAsConstructor.after.kt
index 05cd0f6..ac3ba00 100644
--- a/idea/testData/quickfix/autoImports/noImportInterfaceRefAsConstructor.after.kt
+++ b/idea/testData/quickfix/autoImports/noImportInterfaceRefAsConstructor.after.kt
@@ -1,5 +1,6 @@
 // "Import" "false"
 // ERROR: Unresolved reference: Some
+// ACTION: Convert to expression body
 // ACTION: Create function 'Some'
 // ACTION: Rename reference
 
diff --git a/idea/testData/quickfix/autoImports/noImportInterfaceRefAsConstructor.before.Main.kt b/idea/testData/quickfix/autoImports/noImportInterfaceRefAsConstructor.before.Main.kt
index 05cd0f6..ac3ba00 100644
--- a/idea/testData/quickfix/autoImports/noImportInterfaceRefAsConstructor.before.Main.kt
+++ b/idea/testData/quickfix/autoImports/noImportInterfaceRefAsConstructor.before.Main.kt
@@ -1,5 +1,6 @@
 // "Import" "false"
 // ERROR: Unresolved reference: Some
+// ACTION: Convert to expression body
 // ACTION: Create function 'Some'
 // ACTION: Rename reference
 
diff --git a/idea/testData/quickfix/createFromUsage/createClass/annotationEntry/nestedGroovyAnnotation.before.Main.kt b/idea/testData/quickfix/createFromUsage/createClass/annotationEntry/nestedGroovyAnnotation.before.Main.kt
index f6c7b54..65accbb 100644
--- a/idea/testData/quickfix/createFromUsage/createClass/annotationEntry/nestedGroovyAnnotation.before.Main.kt
+++ b/idea/testData/quickfix/createFromUsage/createClass/annotationEntry/nestedGroovyAnnotation.before.Main.kt
@@ -1,5 +1,6 @@
 // "Create annotation 'foo'" "false"
 // ERROR: Unresolved reference: foo
+// ACTION: Convert to expression body
 // ACTION: Make private
 // ACTION: Make internal
 
diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notAbstractClass.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notAbstractClass.kt
index 85d4182..05bdc0d 100644
--- a/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notAbstractClass.kt
+++ b/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/notAbstractClass.kt
@@ -1,4 +1,5 @@
 // "Create abstract function 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create function 'foo'
 // ACTION: Rename reference
 // ERROR: Unresolved reference: foo
diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/otherExplicitReceiver.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/otherExplicitReceiver.kt
index 029ce3c..5d141b5 100644
--- a/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/otherExplicitReceiver.kt
+++ b/idea/testData/quickfix/createFromUsage/createFunction/call/abstract/otherExplicitReceiver.kt
@@ -1,4 +1,5 @@
 // "Create abstract function 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create extension function 'B.foo'
 // ACTION: Create member function 'B.foo'
 // ACTION: Rename reference
diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/callInAnnotationEntry.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/callInAnnotationEntry.kt
index 4fda12e..f089d47 100644
--- a/idea/testData/quickfix/createFromUsage/createFunction/call/callInAnnotationEntry.kt
+++ b/idea/testData/quickfix/createFromUsage/createFunction/call/callInAnnotationEntry.kt
@@ -4,6 +4,7 @@
 // ACTION: Make private
 // ACTION: Rename reference
 // ACTION: Put arguments on separate lines
+// ACTION: Convert to expression body
 // ERROR: Unresolved reference: foo
 // ERROR: Unresolved reference: bar
 
diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/extensionByExtensionReceiver/notExtensionCallable.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/extensionByExtensionReceiver/notExtensionCallable.kt
index 76e6a3d..f2f0aed 100644
--- a/idea/testData/quickfix/createFromUsage/createFunction/call/extensionByExtensionReceiver/notExtensionCallable.kt
+++ b/idea/testData/quickfix/createFromUsage/createFunction/call/extensionByExtensionReceiver/notExtensionCallable.kt
@@ -1,4 +1,5 @@
 // "Create extension function 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create function 'foo'
 // ACTION: Rename reference
 // ERROR: Unresolved reference: foo
diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/funOnGroovyType.before.Main.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/funOnGroovyType.before.Main.kt
index 2a1cbcd..6fc3b3e 100644
--- a/idea/testData/quickfix/createFromUsage/createFunction/call/funOnGroovyType.before.Main.kt
+++ b/idea/testData/quickfix/createFromUsage/createFunction/call/funOnGroovyType.before.Main.kt
@@ -1,4 +1,5 @@
 // "Create member function 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create extension function 'A.foo'
 // ACTION: Rename reference
 // ERROR: Unresolved reference: foo
diff --git a/idea/testData/quickfix/createFromUsage/createFunction/call/propertyOnUserType.kt b/idea/testData/quickfix/createFromUsage/createFunction/call/propertyOnUserType.kt
index 9f6d59d..d05f216 100644
--- a/idea/testData/quickfix/createFromUsage/createFunction/call/propertyOnUserType.kt
+++ b/idea/testData/quickfix/createFromUsage/createFunction/call/propertyOnUserType.kt
@@ -1,4 +1,5 @@
 // "Create member function 'foo'" "false"
+// ACTION: Convert to expression body
 // ERROR: Unresolved reference: x
 
 class A<T>(val n: T) {
diff --git a/idea/testData/quickfix/createFromUsage/createFunction/callableReferences/noFunctionalType.kt b/idea/testData/quickfix/createFromUsage/createFunction/callableReferences/noFunctionalType.kt
index cb4649d..72b2e95 100644
--- a/idea/testData/quickfix/createFromUsage/createFunction/callableReferences/noFunctionalType.kt
+++ b/idea/testData/quickfix/createFromUsage/createFunction/callableReferences/noFunctionalType.kt
@@ -1,4 +1,5 @@
 // "Create function 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Rename reference
 // ERROR: Unresolved reference: foo
 fun bar(n: Int) = "$n"
diff --git a/idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/inAnnotation.kt b/idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/inAnnotation.kt
index 11ba0f1..afa946d 100644
--- a/idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/inAnnotation.kt
+++ b/idea/testData/quickfix/createFromUsage/createTypeParameter/inContainingDeclaration/inAnnotation.kt
@@ -1,5 +1,6 @@
 // "Create type parameter 'Test' in class 'C'" "false"
 // ACTION: Add 'testng' to classpath
+// ACTION: Convert to expression body
 // ACTION: Create annotation 'Test'
 // ACTION: Make internal
 // ACTION: Make private
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClassObject.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClassObject.kt
index 1810fa1..cf5c520 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClassObject.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInClassObject.kt
@@ -1,4 +1,5 @@
 // "Create parameter 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create local variable 'foo'
 // ACTION: Create property 'foo'
 // ACTION: Rename reference
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInObject.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInObject.kt
index 6bc3316..62aa2b6 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInObject.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInObject.kt
@@ -1,4 +1,5 @@
 // "Create parameter 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create local variable 'foo'
 // ACTION: Create property 'foo'
 // ACTION: Rename reference
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInTrait.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInTrait.kt
index cde3929..bc4a2a1 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInTrait.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorInTrait.kt
@@ -1,4 +1,5 @@
 // "Create parameter 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create local variable 'foo'
 // ACTION: Create abstract property 'foo'
 // ACTION: Rename reference
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorNoClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorNoClass.kt
index c14d9c1..b725735 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorNoClass.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inAccessorNoClass.kt
@@ -1,4 +1,5 @@
 // "Create parameter 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create local variable 'foo'
 // ACTION: Create property 'foo'
 // ACTION: Rename reference
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inGenAccessorInClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inGenAccessorInClass.kt
index 0d781d1..a8bb2e9 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inGenAccessorInClass.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inGenAccessorInClass.kt
@@ -1,4 +1,5 @@
 // "Create parameter 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create local variable 'foo'
 // ACTION: Create property 'foo'
 // ACTION: Create extension property 'T.foo'
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inGenAccessorInGenClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inGenAccessorInGenClass.kt
index 2b9ea8c..09e72c9 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/parameter/inGenAccessorInGenClass.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/parameter/inGenAccessorInGenClass.kt
@@ -1,4 +1,5 @@
 // "Create parameter 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create local variable 'foo'
 // ACTION: Create property 'foo'
 // ACTION: Create extension property 'T.foo'
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/localValNoReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/localValNoReceiver.kt
index 527c791..e90820b 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/localValNoReceiver.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/localValNoReceiver.kt
@@ -1,4 +1,5 @@
 // "Create property 'foo' as constructor parameter" "false"
+// ACTION: Convert to expression body
 // ACTION: Create parameter 'foo'
 // ACTION: Create local variable 'foo'
 // ACTION: Rename reference
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/objectMemberValNoReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/objectMemberValNoReceiver.kt
index d69d34f..4972167 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/objectMemberValNoReceiver.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/objectMemberValNoReceiver.kt
@@ -1,4 +1,5 @@
 // "Create property 'foo' as constructor parameter" "false"
+// ACTION: Convert to expression body
 // ACTION: Create local variable 'foo'
 // ACTION: Create parameter 'foo'
 // ACTION: Create property 'foo'
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/topLevelValNoReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/topLevelValNoReceiver.kt
index cec6b60..05e46c6 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/topLevelValNoReceiver.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/topLevelValNoReceiver.kt
@@ -1,5 +1,6 @@
 // "Create property 'foo' as constructor parameter" "false"
 // ACTION: Create property 'foo'
+// ACTION: Convert to expression body
 // ACTION: Create local variable 'foo'
 // ACTION: Create parameter 'foo'
 // ACTION: Rename reference
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Main.kt b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Main.kt
index c143c0e..f1771ba 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Main.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/primaryParameter/valOnJavaType.before.Main.kt
@@ -1,5 +1,6 @@
 // "Create property 'foo' as constructor parameter" "false"
 // ACTION: Create member property 'A.foo'
+// ACTION: Convert to expression body
 // ACTION: Create extension property 'A.foo'
 // ACTION: Rename reference
 // ERROR: Unresolved reference: foo
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/abstract/notAbstractClass.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/abstract/notAbstractClass.kt
index 089864b..d99f9be 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/property/abstract/notAbstractClass.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/property/abstract/notAbstractClass.kt
@@ -1,4 +1,5 @@
 // "Create abstract property 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create local variable 'foo'
 // ACTION: Create parameter 'foo'
 // ACTION: Create property 'foo'
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/abstract/otherExplicitReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/abstract/otherExplicitReceiver.kt
index 3169cac..98c2264 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/property/abstract/otherExplicitReceiver.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/property/abstract/otherExplicitReceiver.kt
@@ -1,4 +1,5 @@
 // "Create abstract property 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create extension property 'B.foo'
 // ACTION: Create member property 'B.foo'
 // ACTION: Create property 'foo' as constructor parameter
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/localValNoReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/localValNoReceiver.kt
index cddb7e4..f3bb4d2 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/property/localValNoReceiver.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/property/localValNoReceiver.kt
@@ -1,4 +1,5 @@
 // "Create property 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create parameter 'foo'
 // ACTION: Create local variable 'foo'
 // ACTION: Rename reference
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/memberWithTypeParameterAsReceiver.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/memberWithTypeParameterAsReceiver.kt
index e64d4b2..03744b1 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/property/memberWithTypeParameterAsReceiver.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/property/memberWithTypeParameterAsReceiver.kt
@@ -1,6 +1,7 @@
 // "Create member property 'bar'" "false"
 // ACTION: Create extension property 'T.bar'
 // ACTION: Rename reference
+// ACTION: Convert to expression body
 // ERROR: Unresolved reference: bar
 fun consume(n: Int) {}
 
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/valOnGroovyType.before.Main.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/valOnGroovyType.before.Main.kt
index 16337a1..973f367 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/property/valOnGroovyType.before.Main.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/property/valOnGroovyType.before.Main.kt
@@ -1,4 +1,5 @@
 // "Create property 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create extension property 'A.foo'
 // ACTION: Rename reference
 // ERROR: Unresolved reference: foo
diff --git a/idea/testData/quickfix/createFromUsage/createVariable/property/valOnJavaInterface.before.Main.kt b/idea/testData/quickfix/createFromUsage/createVariable/property/valOnJavaInterface.before.Main.kt
index 28e1be2..9d33df7 100644
--- a/idea/testData/quickfix/createFromUsage/createVariable/property/valOnJavaInterface.before.Main.kt
+++ b/idea/testData/quickfix/createFromUsage/createVariable/property/valOnJavaInterface.before.Main.kt
@@ -1,4 +1,5 @@
 // "Create property 'foo'" "false"
+// ACTION: Convert to expression body
 // ACTION: Create extension property 'A.foo'
 // ACTION: Rename reference
 // ERROR: Unresolved reference: foo
diff --git a/idea/testData/quickfix/createLabel/breakNoLoop.kt b/idea/testData/quickfix/createLabel/breakNoLoop.kt
index 410e5f7..29e2106 100644
--- a/idea/testData/quickfix/createLabel/breakNoLoop.kt
+++ b/idea/testData/quickfix/createLabel/breakNoLoop.kt
@@ -1,4 +1,5 @@
 // "Create label foo@" "false"
+// ACTION: Convert to expression body
 // ERROR: The label '@foo' does not denote a loop
 // ERROR: Unresolved reference: @foo
 
diff --git a/idea/testData/quickfix/createLabel/continueNoLoop.kt b/idea/testData/quickfix/createLabel/continueNoLoop.kt
index 8e11684..df19cda 100644
--- a/idea/testData/quickfix/createLabel/continueNoLoop.kt
+++ b/idea/testData/quickfix/createLabel/continueNoLoop.kt
@@ -1,4 +1,5 @@
 // "Create label foo@" "false"
+// ACTION: Convert to expression body
 // ERROR: The label '@foo' does not denote a loop
 // ERROR: Unresolved reference: @foo
 
diff --git a/idea/testData/quickfix/createLabel/returnNoLambda.kt b/idea/testData/quickfix/createLabel/returnNoLambda.kt
index 942ed23..dd4b590 100644
--- a/idea/testData/quickfix/createLabel/returnNoLambda.kt
+++ b/idea/testData/quickfix/createLabel/returnNoLambda.kt
@@ -1,4 +1,5 @@
 // "Create label foo@" "false"
+// ACTION: Convert to expression body
 // ERROR: Unresolved reference: @foo
 
 fun test(): Int {
diff --git a/idea/testData/quickfix/decreaseVisibility/exposedParameterType.kt b/idea/testData/quickfix/decreaseVisibility/exposedParameterType.kt
index 97cc116..5733337 100644
--- a/idea/testData/quickfix/decreaseVisibility/exposedParameterType.kt
+++ b/idea/testData/quickfix/decreaseVisibility/exposedParameterType.kt
@@ -3,6 +3,7 @@
 // ACTION: Make 'Nested' internal
 // ACTION: Make 'Nested' public
 // ACTION: Remove parameter 'arg'
+// ACTION: Convert to expression body
 // ERROR: 'internal' function exposes its 'private' parameter type argument Nested
 // ERROR: Cannot access 'Nested': it is private in 'Outer'
 
diff --git a/idea/testData/quickfix/moveReceiverAnnotation/notExtensionFun.kt b/idea/testData/quickfix/moveReceiverAnnotation/notExtensionFun.kt
index c2cee5e..70b7227 100644
--- a/idea/testData/quickfix/moveReceiverAnnotation/notExtensionFun.kt
+++ b/idea/testData/quickfix/moveReceiverAnnotation/notExtensionFun.kt
@@ -1,5 +1,6 @@
 // "Move annotation to receiver type" "false"
 // ERROR: '@receiver:' annotations can only be applied to the receiver type of extension function or extension property declarations
+// ACTION: Convert to expression body
 // ACTION: Make internal
 // ACTION: Make private
 
diff --git a/idea/testData/quickfix/override/overridingOpenMethodInFinalClass.kt b/idea/testData/quickfix/override/overridingOpenMethodInFinalClass.kt
index 357c3dc..de33d39 100644
--- a/idea/testData/quickfix/override/overridingOpenMethodInFinalClass.kt
+++ b/idea/testData/quickfix/override/overridingOpenMethodInFinalClass.kt
@@ -1,4 +1,5 @@
 // "Make A.foo open" "false"
+// ACTION: Convert to expression body
 // ERROR: This type is final, so it cannot be inherited from
 class A() {
     open fun foo() {}
diff --git a/idea/testData/quickfix/replaceWithSafeCall/noReplaceWithSafeCallForImplicitReceiver.kt b/idea/testData/quickfix/replaceWithSafeCall/noReplaceWithSafeCallForImplicitReceiver.kt
index 200ddff..2d3ad53 100644
--- a/idea/testData/quickfix/replaceWithSafeCall/noReplaceWithSafeCallForImplicitReceiver.kt
+++ b/idea/testData/quickfix/replaceWithSafeCall/noReplaceWithSafeCallForImplicitReceiver.kt
@@ -1,5 +1,6 @@
 // "Replace with safe (?.) call" "false"
 // ACTION: Add non-null asserted (!!) call
+// ACTION: Convert to expression body
 // ACTION: Replace with safe (this?.) call
 // ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type A?
 
diff --git a/idea/testData/quickfix/typeMismatch/casts/preferExclExcl.kt b/idea/testData/quickfix/typeMismatch/casts/preferExclExcl.kt
index 1802768..58b40f6 100644
--- a/idea/testData/quickfix/typeMismatch/casts/preferExclExcl.kt
+++ b/idea/testData/quickfix/typeMismatch/casts/preferExclExcl.kt
@@ -2,6 +2,7 @@
 // ACTION: Add 'toString()' call
 // ACTION: Add non-null asserted (!!) call
 // ACTION: Change parameter 's' type of function 'bar' to 'String?'
+// ACTION: Convert to expression body
 // ACTION: Create function 'bar'
 // ACTION: Surround with null check
 // ACTION: Wrap with '?.let { ... }' call
diff --git a/idea/testData/quickfix/typeMismatch/casts/typeMismatch2.kt b/idea/testData/quickfix/typeMismatch/casts/typeMismatch2.kt
index 6498e86..f72b995 100644
--- a/idea/testData/quickfix/typeMismatch/casts/typeMismatch2.kt
+++ b/idea/testData/quickfix/typeMismatch/casts/typeMismatch2.kt
@@ -1,5 +1,6 @@
 // "Cast expression 'Foo<Number>()' to 'Foo<Int>'" "false"
 // ACTION: Change return type of enclosing function 'foo' to 'Foo<Number>'
+// ACTION: Convert to expression body
 // ERROR: Type mismatch: inferred type is Foo<Number> but Foo<Int> was expected
 class Foo<T>
 
diff --git a/idea/testData/quickfix/typeMismatch/letClassImplementGenericInterfaceTwice.kt b/idea/testData/quickfix/typeMismatch/letClassImplementGenericInterfaceTwice.kt
index e27c8dc..23567b1 100644
--- a/idea/testData/quickfix/typeMismatch/letClassImplementGenericInterfaceTwice.kt
+++ b/idea/testData/quickfix/typeMismatch/letClassImplementGenericInterfaceTwice.kt
@@ -1,5 +1,6 @@
 // "Let 'B' implement interface 'A<Int>'" "false"
 // ACTION: Change parameter 'a' type of function 'let.implement.foo' to 'B'
+// ACTION: Convert to expression body
 // ACTION: Create function 'foo'
 // ERROR: Type mismatch: inferred type is B but A<Int> was expected
 package let.implement
diff --git a/idea/testData/quickfix/typeMismatch/letClassImplementGenericStarInterface.kt b/idea/testData/quickfix/typeMismatch/letClassImplementGenericStarInterface.kt
index 2bbb125..1a9777d 100644
--- a/idea/testData/quickfix/typeMismatch/letClassImplementGenericStarInterface.kt
+++ b/idea/testData/quickfix/typeMismatch/letClassImplementGenericStarInterface.kt
@@ -1,5 +1,6 @@
 // "Let 'B' implement interface 'A<*>'" "false"
 // ACTION: Change parameter 'a' type of function 'let.implement.foo' to 'B'
+// ACTION: Convert to expression body
 // ACTION: Create function 'foo'
 // ERROR: Type mismatch: inferred type is B but A<*> was expected
 
diff --git a/idea/testData/quickfix/typeMismatch/letClassImplementIndirectlyInheritedInterface.kt b/idea/testData/quickfix/typeMismatch/letClassImplementIndirectlyInheritedInterface.kt
index fe45afa..b32d422 100644
--- a/idea/testData/quickfix/typeMismatch/letClassImplementIndirectlyInheritedInterface.kt
+++ b/idea/testData/quickfix/typeMismatch/letClassImplementIndirectlyInheritedInterface.kt
@@ -1,5 +1,6 @@
 // "Let 'B' implement interface 'A<Int>'" "false"
 // ACTION: Change parameter 'a' type of function 'let.implement.foo' to 'B'
+// ACTION: Convert to expression body
 // ACTION: Create function 'foo'
 // ERROR: Type mismatch: inferred type is B but A<Int> was expected
 package let.implement
diff --git a/idea/testData/quickfix/typeMismatch/letStringImplementInterface.kt b/idea/testData/quickfix/typeMismatch/letStringImplementInterface.kt
index 72c7759..04dd8d6 100644
--- a/idea/testData/quickfix/typeMismatch/letStringImplementInterface.kt
+++ b/idea/testData/quickfix/typeMismatch/letStringImplementInterface.kt
@@ -1,5 +1,6 @@
 // "Let 'String' implement interface 'A'" "false"
 // ACTION: Change parameter 'a' type of function 'let.implement.foo' to 'String'
+// ACTION: Convert to expression body
 // ACTION: To raw string literal
 // ACTION: Create function 'foo'
 // ERROR: Type mismatch: inferred type is String but A was expected
diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/multiFakeOverride.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/multiFakeOverride.kt
index e982cc5..664b892 100644
--- a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/multiFakeOverride.kt
+++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/multiFakeOverride.kt
@@ -1,5 +1,6 @@
 // "Change return type of called function 'AA.f' to 'Boolean'" "false"
 // ACTION: Change return type of enclosing function 'AAA.g' to 'Int'
+// ACTION: Convert to expression body
 // ERROR: Type mismatch: inferred type is Int but Boolean was expected
 interface A {
     fun f(): Int
diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/multiFakeOverrideForOperatorConvention.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/multiFakeOverrideForOperatorConvention.kt
index 112a32a..cce29f5 100644
--- a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/multiFakeOverrideForOperatorConvention.kt
+++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/multiFakeOverrideForOperatorConvention.kt
@@ -1,5 +1,6 @@
 // "Change return type of called function 'AA.contains' to 'Int'" "false"
 // ACTION: Change return type of enclosing function 'AAA.g' to 'Boolean'
+// ACTION: Convert to expression body
 // ACTION: Replace overloaded operator with function call
 // ERROR: Type mismatch: inferred type is Boolean but Int was expected
 interface A {
diff --git a/idea/testData/quickfix/unusedSuppressAnnotation/notForDeprecated.kt b/idea/testData/quickfix/unusedSuppressAnnotation/notForDeprecated.kt
index 067d6f6..13fb19b 100644
--- a/idea/testData/quickfix/unusedSuppressAnnotation/notForDeprecated.kt
+++ b/idea/testData/quickfix/unusedSuppressAnnotation/notForDeprecated.kt
@@ -1,5 +1,6 @@
 // "Suppress for declarations annotated by 'kotlin.Deprecated'" "false"
 // ACTION: Safe delete 'foo'
 // ACTION: Create test
+// ACTION: Convert to expression body
 @Deprecated("")
 fun foo<caret>(){}
diff --git a/idea/testData/quickfix/unusedSuppressAnnotation/notForJetBrains.kt b/idea/testData/quickfix/unusedSuppressAnnotation/notForJetBrains.kt
index dfcca8e..1c9efa7 100644
--- a/idea/testData/quickfix/unusedSuppressAnnotation/notForJetBrains.kt
+++ b/idea/testData/quickfix/unusedSuppressAnnotation/notForJetBrains.kt
@@ -1,6 +1,7 @@
 // "Suppress for declarations annotated by 'org.jetbrains.annotations.NonNls'" "false"
 // ACTION: Safe delete 'foo'
 // ACTION: Create test
+// ACTION: Convert to expression body
 import org.jetbrains.annotations.NonNls
 
 @NonNls
diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
index 31a125f..1cb1896 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -6309,6 +6309,255 @@
         }
     }
 
+    @TestMetadata("idea/testData/intentions/convertToExpressionBody")
+    @TestDataPath("$PROJECT_ROOT")
+    @RunWith(JUnit3RunnerWithInners.class)
+    public static class ConvertToExpressionBody extends AbstractIntentionTest {
+        public void testAllFilesPresentInConvertToExpressionBody() throws Exception {
+            KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/convertToExpressionBody"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
+        }
+
+        @TestMetadata("anonymousObjectExpression.kt")
+        public void testAnonymousObjectExpression() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/anonymousObjectExpression.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("assignPlus.kt")
+        public void testAssignPlus() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/assignPlus.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("assignment.kt")
+        public void testAssignment() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/assignment.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("constructorWithEmptyBody.kt")
+        public void testConstructorWithEmptyBody() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/constructorWithEmptyBody.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("declaration.kt")
+        public void testDeclaration() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/declaration.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("elvisIfElseUnit.kt")
+        public void testElvisIfElseUnit() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/elvisIfElseUnit.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("elvisIfUnit.kt")
+        public void testElvisIfUnit() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/elvisIfUnit.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("elvisWhenUnitNonExhaustive.kt")
+        public void testElvisWhenUnitNonExhaustive() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/elvisWhenUnitNonExhaustive.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("emptyList.kt")
+        public void testEmptyList() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/emptyList.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("expressionWithReturns1.kt")
+        public void testExpressionWithReturns1() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/expressionWithReturns1.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("expressionWithReturns2.kt")
+        public void testExpressionWithReturns2() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/expressionWithReturns2.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("funWithEmptyBody.kt")
+        public void testFunWithEmptyBody() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/funWithEmptyBody.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("funWithEmptyBody2.kt")
+        public void testFunWithEmptyBody2() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/funWithEmptyBody2.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("funWithImplicitUnitTypeWithThrow.kt")
+        public void testFunWithImplicitUnitTypeWithThrow() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/funWithImplicitUnitTypeWithThrow.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("funWithNoBlock.kt")
+        public void testFunWithNoBlock() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/funWithNoBlock.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("funWithNothingType.kt")
+        public void testFunWithNothingType() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/funWithNothingType.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("funWithReturn.kt")
+        public void testFunWithReturn() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/funWithReturn.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("funWithUnitType.kt")
+        public void testFunWithUnitType() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/funWithUnitType.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("funWithUnitType2.kt")
+        public void testFunWithUnitType2() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/funWithUnitType2.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("funWithUnitTypeWithThrow.kt")
+        public void testFunWithUnitTypeWithThrow() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/funWithUnitTypeWithThrow.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("functionLiteral.kt")
+        public void testFunctionLiteral() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/functionLiteral.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("getWithReturn.kt")
+        public void testGetWithReturn() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/getWithReturn.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("ifElseUnit.kt")
+        public void testIfElseUnit() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/ifElseUnit.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("ifUnit.kt")
+        public void testIfUnit() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/ifUnit.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("ifWhenUnitExhaustive.kt")
+        public void testIfWhenUnitExhaustive() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/ifWhenUnitExhaustive.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("ifWhenUnitNonExhaustive.kt")
+        public void testIfWhenUnitNonExhaustive() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/ifWhenUnitNonExhaustive.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("lambdaIfUnit.kt")
+        public void testLambdaIfUnit() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/lambdaIfUnit.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("lambdaWhenUnitNonExhaustive.kt")
+        public void testLambdaWhenUnitNonExhaustive() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/lambdaWhenUnitNonExhaustive.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("multipleStatements.kt")
+        public void testMultipleStatements() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/multipleStatements.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("overridePublicFun.kt")
+        public void testOverridePublicFun() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/overridePublicFun.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("returnFromLambda.kt")
+        public void testReturnFromLambda() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/returnFromLambda.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("returnFromLambda2.kt")
+        public void testReturnFromLambda2() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/returnFromLambda2.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("returnWithNoValue.kt")
+        public void testReturnWithNoValue() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/returnWithNoValue.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("whenIfUnitExhaustive.kt")
+        public void testWhenIfUnitExhaustive() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/whenIfUnitExhaustive.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("whenIfUnitNonExhaustive.kt")
+        public void testWhenIfUnitNonExhaustive() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/whenIfUnitNonExhaustive.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("whenUnitExhaustive.kt")
+        public void testWhenUnitExhaustive() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/whenUnitExhaustive.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("whenUnitNonExhaustive.kt")
+        public void testWhenUnitNonExhaustive() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/whenUnitNonExhaustive.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("whenUnitWithElse.kt")
+        public void testWhenUnitWithElse() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/whenUnitWithElse.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("whenWhenNonExhaustive.kt")
+        public void testWhenWhenNonExhaustive() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/whenWhenNonExhaustive.kt");
+            doTest(fileName);
+        }
+
+        @TestMetadata("while.kt")
+        public void testWhile() throws Exception {
+            String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToExpressionBody/while.kt");
+            doTest(fileName);
+        }
+    }
+
     @TestMetadata("idea/testData/intentions/convertToForEachFunctionCall")
     @TestDataPath("$PROJECT_ROOT")
     @RunWith(JUnit3RunnerWithInners.class)