Convert to block body: when expression with Unit result is now handled as "return needed" #KT-12193 Fixed

This commit is contained in:
Mikhail Glukhikh
2016-05-23 11:06:27 +03:00
parent 9a69b8b7b5
commit fa5e284bf8
6 changed files with 64 additions and 1 deletions
@@ -52,16 +52,25 @@ class ConvertToBlockBodyIntention : SelfTargetingIntention<KtDeclarationWithBody
}
companion object {
private fun KtExpression.whenAsResult(): Boolean = when (this) {
is KtWhenExpression -> true
is KtIfExpression -> (then?.whenAsResult() ?: false) || (`else`?.whenAsResult() ?: false)
is KtBlockExpression -> statements.lastOrNull()?.whenAsResult() ?: false
else -> false
}
fun convert(declaration: KtDeclarationWithBody): KtDeclarationWithBody {
val body = declaration.bodyExpression!!
fun generateBody(returnsValue: Boolean): KtExpression {
val bodyType = body.analyze().getType(body)
val unitWhenAsResult = (bodyType == null || KotlinBuiltIns.isUnit(bodyType)) && body.whenAsResult()
val needReturn = returnsValue &&
(bodyType == null || (!KotlinBuiltIns.isUnit(bodyType) && !KotlinBuiltIns.isNothing(bodyType)))
val factory = KtPsiFactory(declaration)
val statement = if (needReturn) factory.createExpressionByPattern("return $0", body) else body
val statement = if (needReturn || unitWhenAsResult) factory.createExpressionByPattern("return $0", body) else body
return factory.createSingleStatementBlock(statement)
}
@@ -0,0 +1,12 @@
enum class AccessMode { READ, WRITE, EXECUTE }
fun foo() {}
fun whenExpr(access: AccessMode, arg: Boolean) = <caret>if (arg) {} else {
foo()
when (access) {
AccessMode.READ -> {}
AccessMode.WRITE -> {}
AccessMode.EXECUTE -> {}
}
}
@@ -0,0 +1,14 @@
enum class AccessMode { READ, WRITE, EXECUTE }
fun foo() {}
fun whenExpr(access: AccessMode, arg: Boolean) {
return if (arg) {} else {
foo()
when (access) {
AccessMode.READ -> {}
AccessMode.WRITE -> {}
AccessMode.EXECUTE -> {}
}
}
}
@@ -0,0 +1,7 @@
enum class AccessMode { READ, WRITE, EXECUTE }
fun whenExpr(access: AccessMode) = <caret>when (access) {
AccessMode.READ -> {}
AccessMode.WRITE -> {}
AccessMode.EXECUTE -> {}
}
@@ -0,0 +1,9 @@
enum class AccessMode { READ, WRITE, EXECUTE }
fun whenExpr(access: AccessMode) {
return when (access) {
AccessMode.READ -> {}
AccessMode.WRITE -> {}
AccessMode.EXECUTE -> {}
}
}
@@ -4225,6 +4225,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("ifWhenUnit.kt")
public void testIfWhenUnit() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToBlockBody/ifWhenUnit.kt");
doTest(fileName);
}
@TestMetadata("implicitlyNonUnitFun.kt")
public void testImplicitlyNonUnitFun() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToBlockBody/implicitlyNonUnitFun.kt");
@@ -4284,6 +4290,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToBlockBody/valueIsAnonymousObject4.kt");
doTest(fileName);
}
@TestMetadata("whenUnit.kt")
public void testWhenUnit() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertToBlockBody/whenUnit.kt");
doTest(fileName);
}
}
@TestMetadata("idea/testData/intentions/convertToConcatenatedString")