From 374ebaafc863c06b7c127a62f88650bcf2b3b6e7 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Wed, 7 Dec 2011 17:44:32 +0400 Subject: [PATCH] KT-539 Switch support --- src/org/jetbrains/jet/j2k/Converter.java | 7 ++ .../jet/j2k/visitors/StatementVisitor.java | 52 +++++++++-- .../jet/j2k/JavaToKotlinConverterTest.java | 2 +- .../ast/switch/file/comlicatedFallDown.jav | 32 +++++++ .../ast/switch/file/comlicatedFallDown.kt | 87 +++++++++++++++++++ .../file/{throwDown.jav => fallDown.jav} | 0 .../switch/file/{throwDown.kt => fallDown.kt} | 0 7 files changed, 171 insertions(+), 9 deletions(-) create mode 100644 testData/ast/switch/file/comlicatedFallDown.jav create mode 100644 testData/ast/switch/file/comlicatedFallDown.kt rename testData/ast/switch/file/{throwDown.jav => fallDown.jav} (100%) rename testData/ast/switch/file/{throwDown.kt => fallDown.kt} (100%) diff --git a/src/org/jetbrains/jet/j2k/Converter.java b/src/org/jetbrains/jet/j2k/Converter.java index 567345265a2..509704cf4bc 100644 --- a/src/org/jetbrains/jet/j2k/Converter.java +++ b/src/org/jetbrains/jet/j2k/Converter.java @@ -388,6 +388,13 @@ public class Converter { return result; } + @NotNull + public static List statementsToStatementList(@NotNull List statements) { + List result = new LinkedList(); + for (PsiStatement t : statements) result.add(statementToStatement(t)); + return result; + } + @NotNull public static Statement statementToStatement(@Nullable PsiStatement s) { if (s == null) return Statement.EMPTY_STATEMENT; diff --git a/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java b/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java index 8c3a9d25eb1..0e3561722c9 100644 --- a/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java +++ b/src/org/jetbrains/jet/j2k/visitors/StatementVisitor.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.j2k.ast.*; import java.util.Arrays; +import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -201,27 +202,62 @@ public class StatementVisitor extends ElementVisitor { super.visitSwitchStatement(statement); myResult = new SwitchContainer( expressionToExpression(statement.getExpression()), - listToCases(splitToCases(statement.getBody())) + switchBodyToCases(statement.getBody()) ); } @NotNull - private static List listToCases(@NotNull final List> cases) { + private static List switchBodyToCases(@Nullable final PsiCodeBlock body) { + final List> cases = splitToCases(body); + final List allSwitchStatements = body != null ? Arrays.asList(body.getStatements()) : Collections.emptyList(); + List result = new LinkedList(); List pendingLabels = new LinkedList(); + int i = 0; for (List ls : cases) { assert ls.size() > 0; PsiStatement label = ls.get(0); assert label instanceof PsiSwitchLabelStatement; + + assert allSwitchStatements.get(i) == label : "not a right index"; + if (ls.size() > 1) { pendingLabels.add(statementToStatement(label)); - result.add(new CaseContainer(pendingLabels, - statementsToStatementList(ls.subList(1, ls.size()).toArray(new PsiStatement[ls.size() - 1])) - )); - pendingLabels = new LinkedList(); - } - else // ls.size() == 1 + List slice = ls.subList(1, ls.size()); + + if (!containsBreak(slice)) { + List statements = statementsToStatementList(slice); + statements.addAll( + statementsToStatementList(getAllToNextBreak(allSwitchStatements, i + ls.size())) + ); + result.add(new CaseContainer(pendingLabels, statements)); + pendingLabels = new LinkedList(); + } else { + result.add(new CaseContainer(pendingLabels, statementsToStatementList(slice))); + pendingLabels = new LinkedList(); + } + } else // ls.size() == 1 pendingLabels.add(statementToStatement(label)); + i += ls.size(); + } + return result; + } + + private static boolean containsBreak(@NotNull final List slice) { + for (PsiStatement s : slice) + if (s instanceof PsiBreakStatement) + return true; + return false; + } + + private static List getAllToNextBreak(@NotNull final List allStatements, final int start) { + List result = new LinkedList(); + for (int i = start; i < allStatements.size(); i++) { + PsiStatement s = allStatements.get(i); + if (s instanceof PsiBreakStatement) + return result; + if (!(s instanceof PsiSwitchLabelStatement)) + result.add(s); } return result; } diff --git a/test/org/jetbrains/jet/j2k/JavaToKotlinConverterTest.java b/test/org/jetbrains/jet/j2k/JavaToKotlinConverterTest.java index 6b7a168efb3..73ed72b01c6 100644 --- a/test/org/jetbrains/jet/j2k/JavaToKotlinConverterTest.java +++ b/test/org/jetbrains/jet/j2k/JavaToKotlinConverterTest.java @@ -84,7 +84,7 @@ public class JavaToKotlinConverterTest extends LightDaemonAnalyzerTestCase { public static Test suite() { TestSuite suite = new TestSuite(); - suite.addTest(TestCaseBuilder.suiteForDirectory(getTestDataPathBase(), "/ast", true, new TestCaseBuilder.NamedTestFactory() { + suite.addTest(TestCaseBuilder.suiteForDirectory(getTestDataPathBase(), "/ast/switch", true, new TestCaseBuilder.NamedTestFactory() { @NotNull @Override public Test createTest(@NotNull String dataPath, @NotNull String name) { diff --git a/testData/ast/switch/file/comlicatedFallDown.jav b/testData/ast/switch/file/comlicatedFallDown.jav new file mode 100644 index 00000000000..7bede23f75c --- /dev/null +++ b/testData/ast/switch/file/comlicatedFallDown.jav @@ -0,0 +1,32 @@ +package demo; + +public class SwitchDemo { + public static void print(Object o) { + System.out.println(o); + } + + public static void test(int i) { + String monthString = ""; + switch (i) { + case 1: print(1); + case 2: print(2); + case 3: print(3); + case 4: print(4); + case 5: print(5); break; + case 6: print(6); + case 7: print(7); + case 8: print(8); + case 9: print(9); + case 10: print(10); + case 11: print(11); + case 12: monthString = "December"; break; + default: monthString = "Invalid month"; break; + } + System.out.println(monthString); + } + + public static void main(String[] args) { + for (int i = 1; i <=12 ; i++) + test(i); + } +} \ No newline at end of file diff --git a/testData/ast/switch/file/comlicatedFallDown.kt b/testData/ast/switch/file/comlicatedFallDown.kt new file mode 100644 index 00000000000..54abfcf4618 --- /dev/null +++ b/testData/ast/switch/file/comlicatedFallDown.kt @@ -0,0 +1,87 @@ +namespace demo +public open class SwitchDemo() { +class object { +open public fun print(o : Any?) : Unit { +System.out?.println(o) +} +open public fun test(i : Int) : Unit { +var monthString : String? = "" +when (i) { +1 => { +print(1) +print(2) +print(3) +print(4) +print(5) +} +2 => { +print(2) +print(3) +print(4) +print(5) +} +3 => { +print(3) +print(4) +print(5) +} +4 => { +print(4) +print(5) +} +5 => { +print(5) +} +6 => { +print(6) +print(7) +print(8) +print(9) +print(10) +print(11) +monthString = "December" +} +7 => { +print(7) +print(8) +print(9) +print(10) +print(11) +monthString = "December" +} +8 => { +print(8) +print(9) +print(10) +print(11) +monthString = "December" +} +9 => { +print(9) +print(10) +print(11) +monthString = "December" +} +10 => { +print(10) +print(11) +monthString = "December" +} +11 => { +print(11) +monthString = "December" +} +12 => { +monthString = "December" +} +else => { +monthString = "Invalid month" +} +} +System.out?.println(monthString) +} +open public fun main(args : Array?) : Unit { +for (i in 1..12) test(i) +} +} +} \ No newline at end of file diff --git a/testData/ast/switch/file/throwDown.jav b/testData/ast/switch/file/fallDown.jav similarity index 100% rename from testData/ast/switch/file/throwDown.jav rename to testData/ast/switch/file/fallDown.jav diff --git a/testData/ast/switch/file/throwDown.kt b/testData/ast/switch/file/fallDown.kt similarity index 100% rename from testData/ast/switch/file/throwDown.kt rename to testData/ast/switch/file/fallDown.kt