New J2K: Fix statement conversion in a case of inner blocks

This commit is contained in:
Ilya Kirillov
2019-01-26 03:01:04 +03:00
committed by Ilya Kirillov
parent d7962afd05
commit 9fcdb7dde7
@@ -10,7 +10,9 @@ import com.intellij.psi.controlFlow.ControlFlowFactory
import com.intellij.psi.controlFlow.ControlFlowUtil import com.intellij.psi.controlFlow.ControlFlowUtil
import com.intellij.psi.controlFlow.LocalsOrMyInstanceFieldsControlFlowPolicy import com.intellij.psi.controlFlow.LocalsOrMyInstanceFieldsControlFlowPolicy
import org.jetbrains.kotlin.j2k.ConversionContext import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.blockStatement
import org.jetbrains.kotlin.j2k.copyTreeAndDetach import org.jetbrains.kotlin.j2k.copyTreeAndDetach
import org.jetbrains.kotlin.j2k.runExpression
import org.jetbrains.kotlin.j2k.tree.* import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.impl.* import org.jetbrains.kotlin.j2k.tree.impl.*
@@ -39,14 +41,20 @@ class SwitchStatementConversion(private val context: ConversionContext) : Recurs
val statements = cases val statements = cases
.takeWhileInclusive { it.statements.fallsThrough() } .takeWhileInclusive { it.statements.fallsThrough() }
.flatMap { it.statements } .flatMap { it.statements }
.flatMap { it.singleListOrBlockStatements() } .takeWhileInclusive { it.singleListOrBlockStatements().none { isSwitchBreak(it) } }
.takeWhile { !isSwitchBreak(it) } .mapNotNull { statement ->
.map { it.copyTreeAndDetach() } when {
.let { statement is JKBlockStatement ->
if (it.size == 1 && cases.first().statements.singleOrNull() is JKBlockStatement) blockStatement(
listOf(JKBlockStatementImpl(JKBlockImpl(it))) statement.block.statements
else it .takeWhile { !isSwitchBreak(it) }
.map { it.copyTreeAndDetach() }
)
isSwitchBreak(statement) -> null
else -> statement.copyTreeAndDetach()
}
} }
val javaLabels = cases val javaLabels = cases
.takeWhileInclusive { it.statements.isEmpty() } .takeWhileInclusive { it.statements.isEmpty() }
@@ -56,12 +64,12 @@ class SwitchStatementConversion(private val context: ConversionContext) : Recurs
val elseLabel = javaLabels val elseLabel = javaLabels
.find { it is JKJavaDefaultSwitchCaseImpl } .find { it is JKJavaDefaultSwitchCaseImpl }
?.let { JKKtElseWhenLabelImpl() } ?.let { JKKtElseWhenLabelImpl() }
val elseWhenCase = elseLabel?.let { val elseWhenCase = elseLabel?.let { label ->
JKKtWhenCaseImpl(listOf(it), statements.map { it.copyTreeAndDetach() }.blockOrSingle()) JKKtWhenCaseImpl(listOf(label), statements.map { it.copyTreeAndDetach() }.singleBlockOrWrapToRun())
} }
val mainWhenCase = val mainWhenCase =
if (statementLabels.isNotEmpty()) { if (statementLabels.isNotEmpty()) {
JKKtWhenCaseImpl(statementLabels, statements.blockOrSingle()) JKKtWhenCaseImpl(statementLabels, statements.singleBlockOrWrapToRun())
} else null } else null
listOfNotNull(mainWhenCase) + listOfNotNull(mainWhenCase) +
listOfNotNull(elseWhenCase) + listOfNotNull(elseWhenCase) +
@@ -71,9 +79,19 @@ class SwitchStatementConversion(private val context: ConversionContext) : Recurs
private fun <T> List<T>.takeWhileInclusive(predicate: (T) -> Boolean): List<T> = private fun <T> List<T>.takeWhileInclusive(predicate: (T) -> Boolean): List<T> =
takeWhile(predicate) + listOfNotNull(find { !predicate(it) }) takeWhile(predicate) + listOfNotNull(find { !predicate(it) })
private fun List<JKStatement>.blockOrSingle(): JKStatement = private fun List<JKStatement>.singleBlockOrWrapToRun(): JKStatement =
singleOrNull() singleOrNull()
?: JKBlockStatementImpl(JKBlockImpl(this)) ?: JKBlockStatementImpl(
JKBlockImpl(map { statement ->
when (statement) {
is JKBlockStatement ->
JKExpressionStatementImpl(
runExpression(statement, context.symbolProvider)
)
else -> statement
}
})
)
private fun JKStatement.singleListOrBlockStatements(): List<JKStatement> = private fun JKStatement.singleListOrBlockStatements(): List<JKStatement> =