From 8d290ee127d039ad0238dc65325fb33670967fe4 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Mon, 7 Jul 2014 20:02:32 +0400 Subject: [PATCH] Java to Kotlin converter: better switch conversion in case of code block in case --- .../jet/j2k/visitors/StatementVisitor.kt | 30 +++++++++++++++---- .../JavaToKotlinConverterTestGenerated.java | 5 ++++ .../testData/ast/switch/caseWithBlock.java | 20 +++++++++++++ .../testData/ast/switch/caseWithBlock.kt | 17 +++++++++++ 4 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 j2k/tests/testData/ast/switch/caseWithBlock.java create mode 100644 j2k/tests/testData/ast/switch/caseWithBlock.kt diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt b/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt index 09fd606fa23..027686d7d3d 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.kt @@ -216,18 +216,33 @@ open class StatementVisitor(public val converter: Converter) : JavaElementVisito fun isSwitchBreak(statement: PsiStatement) = statement is PsiBreakStatement && statement.getLabelIdentifier() == null - fun convertStatements(statements: List): List - = statements.filterNot(::isSwitchBreak).map { converter.convertStatement(it) } + fun convertStatements(statements: List): List { + val statementsToKeep = statements.filterNot(::isSwitchBreak) + if (statementsToKeep.size == 1) { + val block = statementsToKeep.single() as? PsiBlockStatement + if (block != null) { + return listOf(converter.convertBlock(block.getCodeBlock(), true, { !isSwitchBreak(it) })) + } + } + return statementsToKeep.map { converter.convertStatement(it) } + } fun convertCaseStatements(caseIndex: Int): List { val case = cases[caseIndex] - return if (case.statements.any { it is PsiBreakStatement || it is PsiContinueStatement || it is PsiReturnStatement || it is PsiThrowStatement } || - caseIndex == cases.lastIndex) { - convertStatements(case.statements) + val fallsThrough = if (caseIndex == cases.lastIndex) { + false } - else { // otherwise we fall through into the next case + else { + val block = case.statements.singleOrNull2() as? PsiBlockStatement + 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 convertStatements(case.statements) + convertCaseStatements(caseIndex + 1) } + else { + convertStatements(case.statements) + } } fun convertCaseStatementsToBody(caseIndex: Int): Statement { @@ -399,4 +414,7 @@ open class StatementVisitor(public val converter: Converter) : JavaElementVisito else converter.convertStatement(statement) } + + private fun List.singleOrNull2(): T? + = if (size == 1) this[0] else null } 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 26afc5a999e..fec40a87653 100644 --- a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java +++ b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java @@ -2596,6 +2596,11 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("j2k/tests/testData/ast/switch"), Pattern.compile("^(.+)\\.java$"), true); } + @TestMetadata("caseWithBlock.java") + public void testCaseWithBlock() throws Exception { + doTest("j2k/tests/testData/ast/switch/caseWithBlock.java"); + } + @TestMetadata("comlicatedFallDown.java") public void testComlicatedFallDown() throws Exception { doTest("j2k/tests/testData/ast/switch/comlicatedFallDown.java"); diff --git a/j2k/tests/testData/ast/switch/caseWithBlock.java b/j2k/tests/testData/ast/switch/caseWithBlock.java new file mode 100644 index 00000000000..4e201677698 --- /dev/null +++ b/j2k/tests/testData/ast/switch/caseWithBlock.java @@ -0,0 +1,20 @@ +//method +void foo() { + switch(a) { + case 1: { + int x = 1; + System.out.println(x); + break; + } + + case 2: { + int x = 2; + System.out.println(x); + } + break; + + case 3: { + System.out.println(3); + } + } +} \ No newline at end of file diff --git a/j2k/tests/testData/ast/switch/caseWithBlock.kt b/j2k/tests/testData/ast/switch/caseWithBlock.kt new file mode 100644 index 00000000000..81ce65fdae5 --- /dev/null +++ b/j2k/tests/testData/ast/switch/caseWithBlock.kt @@ -0,0 +1,17 @@ +fun foo() { + when (a) { + 1 -> { + val x = 1 + System.out.println(x) + } + + 2 -> { + val x = 2 + System.out.println(x) + } + + 3 -> { + System.out.println(3) + } + } +} \ No newline at end of file