From d5f0af15c3e84783ab68f4bb29969d32cfbd9d4d Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 10 Jul 2014 18:49:04 +0400 Subject: [PATCH] Java to Kotlin converter: fixed some bugs in switch statement conversion --- .../jet/j2k/visitors/SwitchConverter.kt | 40 ++++++++++--------- .../JavaToKotlinConverterTestGenerated.java | 5 +++ .../ast/switch/fallDownWithBlocks.java | 16 ++++++++ .../testData/ast/switch/fallDownWithBlocks.kt | 24 +++++++++++ 4 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 j2k/tests/testData/ast/switch/fallDownWithBlocks.java create mode 100644 j2k/tests/testData/ast/switch/fallDownWithBlocks.kt diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/SwitchConverter.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/SwitchConverter.kt index 0536490fe4a..2b9f5e8fff7 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/SwitchConverter.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/SwitchConverter.kt @@ -50,32 +50,36 @@ class SwitchConverter(private val converter: Converter) { private fun splitToCases(body: PsiCodeBlock?): List { val cases = ArrayList() - var currentCaseStatements = ArrayList() if (body != null) { - var label: PsiSwitchLabelStatement? = null + var currentLabel: PsiSwitchLabelStatement? = null + var currentCaseStatements = ArrayList() + + fun flushCurrentCase() { + if (currentLabel != null || currentCaseStatements.isNotEmpty()) { + cases.add(Case(currentLabel, currentCaseStatements)) + } + } + for (statement in body.getStatements()) { if (statement is PsiSwitchLabelStatement) { - if (label != null) { - cases.add(Case(label, currentCaseStatements)) - currentCaseStatements = ArrayList() - } - label = statement + flushCurrentCase() + currentLabel = statement + currentCaseStatements = ArrayList() } else { currentCaseStatements.add(statement) } } - if (label != null || currentCaseStatements.isNotEmpty()) { - cases.add(Case(label, currentCaseStatements)) - } + + flushCurrentCase() } return cases } - private fun convertCaseStatements(statements: List): List { + private fun convertCaseStatements(statements: List, allowBlock: Boolean = true): List { val statementsToKeep = statements.filter { !isSwitchBreak(it) } - if (statementsToKeep.size == 1) { + if (allowBlock && statementsToKeep.size == 1) { val block = statementsToKeep.single() as? PsiBlockStatement if (block != null) { return listOf(converter.convertBlock(block.getCodeBlock(), true, { !isSwitchBreak(it) })) @@ -84,7 +88,7 @@ class SwitchConverter(private val converter: Converter) { return statementsToKeep.map { converter.convertStatement(it) } } - private fun convertCaseStatements(cases: List, caseIndex: Int): List { + private fun convertCaseStatements(cases: List, caseIndex: Int, allowBlock: Boolean = true): List { val case = cases[caseIndex] val fallsThrough = if (caseIndex == cases.lastIndex) { false @@ -94,12 +98,10 @@ class SwitchConverter(private val converter: Converter) { val statements = if (block != null) block.getCodeBlock().getStatements().toList() else case.statements !statements.any { it is PsiBreakStatement || it is PsiContinueStatement || it is PsiReturnStatement || it is PsiThrowStatement } } - return if (fallsThrough) { // we fall through into the next case - convertCaseStatements(case.statements) + convertCaseStatements(cases, caseIndex + 1) - } - else { - convertCaseStatements(case.statements) - } + return if (fallsThrough) // we fall through into the next case + convertCaseStatements(case.statements, allowBlock = false) + convertCaseStatements(cases, caseIndex + 1, allowBlock = false) + else + convertCaseStatements(case.statements, allowBlock) } private fun convertCaseStatementsToBody(cases: List, caseIndex: Int): Statement { diff --git a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java index 39256499c4e..68536b6a2f2 100644 --- a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java +++ b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java @@ -2691,6 +2691,11 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv doTest("j2k/tests/testData/ast/switch/fallDown.java"); } + @TestMetadata("fallDownWithBlocks.java") + public void testFallDownWithBlocks() throws Exception { + doTest("j2k/tests/testData/ast/switch/fallDownWithBlocks.java"); + } + @TestMetadata("invalidSwitch.java") public void testInvalidSwitch() throws Exception { doTest("j2k/tests/testData/ast/switch/invalidSwitch.java"); diff --git a/j2k/tests/testData/ast/switch/fallDownWithBlocks.java b/j2k/tests/testData/ast/switch/fallDownWithBlocks.java new file mode 100644 index 00000000000..7be97efe62d --- /dev/null +++ b/j2k/tests/testData/ast/switch/fallDownWithBlocks.java @@ -0,0 +1,16 @@ +//file +public class C { + public static void main(String[] args) { + switch (args.length) { + case 1: { + int a = 1; + System.out.print("1"); + } + + case 2: { + int a = 2; + System.out.print("2"); + } + } + } +} \ No newline at end of file diff --git a/j2k/tests/testData/ast/switch/fallDownWithBlocks.kt b/j2k/tests/testData/ast/switch/fallDownWithBlocks.kt new file mode 100644 index 00000000000..3bbd64c6a93 --- /dev/null +++ b/j2k/tests/testData/ast/switch/fallDownWithBlocks.kt @@ -0,0 +1,24 @@ +public class C { + class object { + public fun main(args: Array) { + when (args.size) { + 1 -> { + run { + val a = 1 + System.out.print("1") + } + run { + val a = 2 + System.out.print("2") + } + } + + 2 -> { + val a = 2 + System.out.print("2") + } + } + } + } +} +fun main(args: Array) = C.main(args) \ No newline at end of file