diff --git a/migrator/src/com/ohos/migrator/java/JavaTransformer.java b/migrator/src/com/ohos/migrator/java/JavaTransformer.java index b0eb95d5a4462a485122bc9190497df411651e8c..0b72ba5c919ac103689baee2b6a41633fb549e5a 100644 --- a/migrator/src/com/ohos/migrator/java/JavaTransformer.java +++ b/migrator/src/com/ohos/migrator/java/JavaTransformer.java @@ -27,6 +27,7 @@ import org.eclipse.jdt.core.dom.*; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Stack; @@ -42,6 +43,7 @@ public class JavaTransformer extends ASTVisitor implements Transformer { private final Stack stsSaved = new Stack<>(); private final String INSTANCE_INITIALIZER = "INSTANCE_INITIALIZER"; + private final String USED_IN_ANOTHER_CASE_CLAUSE = "USED_IN_ANOTHER_CASE_CLAUSE"; private static int countStmtTotal = 0; private static int countExprTotal = 0; @@ -432,6 +434,8 @@ public class JavaTransformer extends ASTVisitor implements Transformer { stsMemberContext = new ClassMemberContext(stsCurrent, 0); else if (isInInterfaceContext) stsMemberContext = new InterfaceMemberContext(stsCurrent, 0); + else if (stsCurrent instanceof BlockContext || stsCurrent instanceof ConstructorBodyContext) + stsMemberContext = new StatementOrLocalDeclarationContext(stsCurrent, 0); else stsMemberContext = new TopDeclarationContext(stsCurrent, 0); @@ -1490,6 +1494,10 @@ public class JavaTransformer extends ASTVisitor implements Transformer { } private void createAndFillVarOrConstDeclarationList(int javaModifiers, List javaVarDeclFragments, Type javaType) { + createAndFillVarOrConstDeclarationList(javaModifiers, javaVarDeclFragments, javaType, true); + } + + private void createAndFillVarOrConstDeclarationList(int javaModifiers, List javaVarDeclFragments, Type javaType, boolean translateVarInitializers) { pushCurrent(createVarOrConstDeclarationList(javaModifiers)); for (VariableDeclarationFragment javaVarDeclFragment : javaVarDeclFragments) { @@ -1502,13 +1510,15 @@ public class JavaTransformer extends ASTVisitor implements Transformer { javaType.accept(this); popCurrent(); // TypeAnnotationContext - Expression javaInitializer = javaVarDeclFragment.getInitializer(); + if (translateVarInitializers) { + Expression javaInitializer = javaVarDeclFragment.getInitializer(); - if (javaInitializer != null) { - pushCurrent(new InitializerContext(stsCurrent, 0)); - stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); - javaInitializer.accept(this); - popCurrent(); // InitializerContext + if (javaInitializer != null) { + pushCurrent(new InitializerContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); + javaInitializer.accept(this); + popCurrent(); // InitializerContext + } } popCurrent(); // VarOrConstDeclaration @@ -2413,6 +2423,326 @@ public class JavaTransformer extends ASTVisitor implements Transformer { return false; } + // Java tree: + // TypeDeclarationStatement: + // TypeDeclaration + // EnumDeclaration + // STS tree: + // statementOrLocalDeclaration: + // | classDeclaration + // | enumDeclaration + @Override + public boolean visit(TypeDeclarationStatement javaTypeDeclarationStmt) { + javaTypeDeclarationStmt.getDeclaration().accept(this); + + ++countStmtTransformed; + return false; + } + + // Java tree: + // switch ( Expression ) + // { { SwitchCase | Statement } } + // SwitchCase: + // case Expression : + // default : + // STS tree: + // switchStatement: + // switch OpenParen singleExpression CloseParen caseBlock + // caseBlock: + // OpenBrace leftCases=caseClauses? defaultClause? rightCases=caseClauses? CloseBrace + // caseClauses: + // caseClause+ + // caseClause: + // case singleExpression ':' statement* + // defaultClause: + // default ':' statement* + @Override + public boolean visit(SwitchStatement javaSwitchStmt) { + SwitchStatementContext stsSwitch = new SwitchStatementContext(stsCurrent, 0); + pushStatement(stsSwitch); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Switch)); + + javaSwitchStmt.getExpression().accept(this); + + CaseBlockContext stsCaseBlock = new CaseBlockContext(stsCurrent, 0); + stsCaseBlock.leftCases = null; + stsCaseBlock.rightCases = null; + pushCurrent(stsCaseBlock); + + List javaVariablesToMove = new ArrayList<>(); + SwitchCase javaCurrentSwitchCase = null; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + if (javaStmt.getNodeType() == ASTNode.SWITCH_CASE) { + javaCurrentSwitchCase = (SwitchCase) javaStmt; + } + else if (javaStmt.getNodeType() == ASTNode.TYPE_DECLARATION_STATEMENT) { + wrapCaseClauseStatementsWithBlock(); + } + else if (javaStmt.getNodeType() == ASTNode.VARIABLE_DECLARATION_STATEMENT) { + processSwitchCaseVariableDeclaration((VariableDeclarationStatement) javaStmt, javaCurrentSwitchCase, + javaSwitchStmt, javaVariablesToMove); + + // We've already processed variable declaration, proceed to the next statement. + continue; + } + + javaStmt.accept(this); + } + + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + // Create CaseClausesContext node and transfer all cases translated thus far to it. + // If we've seen default node, initialize rightCases field of CaseBlockContext node; + // otherwise, initialize leftCases field of CaseBlockContext node. + CaseClausesContext stsCaseClauses = createAndFillCaseClausesContext(stsCaseBlock); + if (stsCaseBlock.defaultClause() != null) { + stsCaseBlock.rightCases = stsCaseClauses; + } + else { + stsCaseBlock.leftCases = stsCaseClauses; + } + + popCurrent(); // CaseBlockContext + popStatement(); // SwitchStatementContext + + // Move variable declarations in front of switch statement, and enclose both + // declarations and switch with additional block. + if (javaVariablesToMove != null && !javaVariablesToMove.isEmpty()) { + // Remove switch statement from current STS node. + stsCurrent.removeLastChild(); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + + for (VariableDeclarationFragment javaVarFragment : javaVariablesToMove) { + VariableDeclarationStatement javaVarDeclStmt = (VariableDeclarationStatement) javaVarFragment.getParent(); + + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + + ArrayList declFragmentList = new ArrayList<>(); + declFragmentList.add(javaVarFragment); + + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), declFragmentList, javaVarDeclStmt.getType(), false); + popStatement(); // VariableOrConstantDeclarationContext + } + + pushStatement(stsSwitch); + popStatement(); // SwitchContext + + popStatement(); // BlockContext + } + + ++countStmtTransformed; + return false; + } + + @Override + public boolean visit(SwitchCase javaSwitchCase) { + // Close the last case clause. + popCaseClauseIfNeeded(); // CaseClauseContext | DefaultClauseContext + + assert(stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseBlock); + CaseBlockContext stsCaseBlock = (CaseBlockContext)stsCurrent; + + if (javaSwitchCase.isDefault()) { + // If any cases have been translated thus far, create CaseClauseContext node, + // transfer those cases to it, and initialize leftCases field of CaseBlockContext node. + stsCaseBlock.leftCases = createAndFillCaseClausesContext(stsCaseBlock); + + // Translate default clause + pushCurrent(new DefaultClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Default)); + } + else { + pushCurrent(new CaseClauseContext(stsCurrent, 0)); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Case)); + javaSwitchCase.getExpression().accept(this); + } + + // SwitchCase is treated as Statement node, thus increment the count. + ++countStmtTransformed; + return false; + } + + private CaseClausesContext createAndFillCaseClausesContext(CaseBlockContext stsCaseBlock) { + List stsCaseList = stsCaseBlock.getRuleContexts(CaseClauseContext.class); + CaseClausesContext stsCaseClauses = null; + + if (!stsCaseList.isEmpty()) { + stsCaseClauses = new CaseClausesContext(stsCurrent, 0); + for (CaseClauseContext stsCase : stsCaseList) { + stsCaseClauses.addChild(stsCase).setParent(stsCaseClauses); + } + stsCaseBlock.children.removeAll(stsCaseList); + + // Add CaseClauseContext node to CaseBlockContext + stsCaseBlock.addChild(stsCaseClauses).setParent(stsCaseBlock); + } + + return stsCaseClauses; + } + private void popCaseClauseIfNeeded() { + // Check if we need to pop additional block added as work around to add + // local declarations to case clause (see wrapCaseClauseStatementsWithBlock() + // method for details). + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) { + popStatement(); // BlockContext + } + + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause + || stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause) { + popCurrent(); // CaseClauseContext | DefaultClauseContext + } + } + + private void wrapCaseClauseStatementsWithBlock() { + // In StaticTS, CaseClause may contain only statements, and is not allowed to + // have local declarations. In contrast, Java permits to have local declarations + // in case clause scope, so when encounter one, wrap up all statements in case clause + // with additional block as a workaround, (since block can have local declarations). + + // Check if already inserted additional block. + if (stsCurrent.getRuleIndex() == StaticTSParser.RULE_block) + return; + + assert stsCurrent.getRuleIndex() == StaticTSParser.RULE_caseClause || + stsCurrent.getRuleIndex() == StaticTSParser.RULE_defaultClause; + + List stsCaseStmts = stsCurrent.getRuleContexts(StatementContext.class); + stsCurrent.children.removeAll(stsCaseStmts); + + BlockContext stsBlock = new BlockContext(stsCurrent, 0); + pushStatement(stsBlock); + for (StatementContext stsStmt : stsCaseStmts) { + StatementOrLocalDeclarationContext stsStmtOrLocalDecl = new StatementOrLocalDeclarationContext(stsBlock, 0); + stsStmtOrLocalDecl.addChild(stsStmt).setParent(stsStmtOrLocalDecl); + stsBlock.addChild(stsStmtOrLocalDecl).setParent(stsBlock); + } + } + + + private void processSwitchCaseVariableDeclaration(VariableDeclarationStatement javaVarDeclStmt, SwitchCase javaCurrentSwitchCase, + SwitchStatement javaSwitchStmt, List javaVariablesToMove) { + // Java permits to declare local variables in switch scope. Such variables exist + // in all following case clauses. In StaticTS, case clauses don't have a common + // scope, and allow only statements, not declarations. To work around this, we + // have to track whether a particular local variable has been referenced in another + // case clause and, in such case, move declaration of that variable in front of + // switch statement, additionally enclosing both variable declaration and switch + // statement, so that variables are only visible in context of switch statement. + + List javaVarFragments = javaVarDeclStmt.fragments(); + for (VariableDeclarationFragment javaVarFragment : javaVarFragments) { + if (isUsedInAnotherCaseClause(javaVarFragment, javaCurrentSwitchCase, javaSwitchStmt)) { + javaVariablesToMove.add(javaVarFragment); + + // Since evaluation of initializer expression can cause side effects, + // in order to preserve the behaviour and result of program, all + // expressions must evaluate in the same order as before. For that + // purpose, we move the variable declaration without initializer part + // and replace initialization with simple assignment. + Expression javaInitExpr = javaVarFragment.getInitializer(); + if (javaInitExpr != null) { + pushStatement(new ExpressionStatementContext(stsCurrent, 0)); + pushCurrent(new AssignmentExpressionContext(pushSingleExpression())); + + javaVarFragment.getName().accept(this); + stsCurrent.addChild(NodeBuilder.terminalNode(StaticTSParser.Assign)); + javaInitExpr.accept(this); + + popSingleExpression(); // AssignmentExpressionContext; + popStatement(); // ExpressionStatementContext + } + } else { + wrapCaseClauseStatementsWithBlock(); + + // For variables, that don't need to be moved, emit single variable + // declaration here to preserve the correct order of evaluation of + // initializer expressions (including assignments emitted for variables + // that are moved). + pushStatement(new VariableOrConstantDeclarationContext(null, 0)); + + ArrayList declFragmentList = new ArrayList<>(); + declFragmentList.add(javaVarFragment); + + createAndFillVarOrConstDeclarationList(javaVarDeclStmt.getModifiers(), declFragmentList, javaVarDeclStmt.getType()); + popStatement(); // VariableOrConstantDeclarationContext + } + } + + ++countStmtTransformed; + } + + private boolean isUsedInAnotherCaseClause(VariableDeclarationFragment javaVarDecl, SwitchCase javaSwitchCase, + SwitchStatement javaSwitchStmt) { + IVariableBinding javaVarBinding = javaVarDecl.resolveBinding(); + + ASTVisitor localVarUsageLookupVisitor = new ASTVisitor() { + boolean done = false; + int nestedSwitchCount = 0; + SwitchCase currentSwitchCase = null; + + @Override + public boolean preVisit2(ASTNode javaNode) { + // This line will prevent from visiting further AST nodes, + // once we are done with the work. + return !done; + } + + @Override + public boolean visit(SimpleName javaName) { + IBinding binding = javaName.resolveBinding(); + + if (binding.equals(javaVarBinding) && javaSwitchCase != currentSwitchCase) { + javaVarDecl.setProperty(USED_IN_ANOTHER_CASE_CLAUSE, true); + done = true; + } + + return false; + } + + @Override + public boolean visit(VariableDeclarationFragment javaVarDeclFragment) { + // Do NOT visit declaration of the variable that we are looking up. + return javaVarDeclFragment != javaVarDecl; + } + + @Override + public boolean visit(SwitchCase javaSwitchCase) { + // Do not change currentSwitchCase when visiting nested switch statements. + if (nestedSwitchCount == 0) { + currentSwitchCase = javaSwitchCase; + } + + return false; + } + + @Override + public boolean visit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount++; + return true; + } + + @Override + public void endVisit(SwitchStatement javaSwitchStatement) { + nestedSwitchCount--; + } + }; + + List javaStmts = javaSwitchStmt.statements(); + for (Statement javaStmt : javaStmts) { + javaStmt.accept(localVarUsageLookupVisitor); + + if (javaVarDecl.getProperty(USED_IN_ANOTHER_CASE_CLAUSE) != null) + return true; + } + + return false; + } + // The list of not yet translated Java Expressions: // Expression: // Annotation, diff --git a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java index 13b5c09ff97a4b80cf61a7c6e6f23c2f8b988148..9835f278051dac775c76b145f4adab44f58333d5 100644 --- a/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java +++ b/migrator/src/com/ohos/migrator/staticTS/writer/StaticTSWriter.java @@ -1000,9 +1000,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // continueStatement: Continue Identifier? SemiColon @Override public Void visitContinueStatement(ContinueStatementContext stsContinueStatement) { - if (!doNeededIndent()) { - sb.append(' '); - } + doNeededIndent(); sb.append(stsContinueStatement.Continue().getText()); TerminalNode termIdentifier = stsContinueStatement.Identifier(); @@ -1018,10 +1016,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { // breakStatement: Break Identifier? SemiColon @Override public Void visitBreakStatement(BreakStatementContext stsBreakStatement) { - if (!doNeededIndent()) { - sb.append(' '); - } - + doNeededIndent(); sb.append(stsBreakStatement.Break().getText()); TerminalNode termIdentifier = stsBreakStatement.Identifier(); @@ -1089,11 +1084,12 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { public Void visitSwitchStatement(SwitchStatementContext stsSwitchStatement) { doNeededIndent(); - sb.append(stsSwitchStatement.Switch().getText()).append('('); + sb.append(stsSwitchStatement.Switch().getText()).append(" ("); stsSwitchStatement.singleExpression().accept(this); - sb.append(")\n"); + sb.append(')'); visitCaseBlock(stsSwitchStatement.caseBlock()); + sb.append('\n'); return null; } @@ -1122,7 +1118,7 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { } indentDecrement(); - sb.append(indentCurrent).append("}\n\n"); + sb.append(indentCurrent).append("}\n"); return null; } @@ -1131,7 +1127,6 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { @Override public Void visitCaseClauses(CaseClausesContext stsCaseClauses) { List stsCaseClauseList = stsCaseClauses.caseClause(); - for (CaseClauseContext stsCaseClause : stsCaseClauseList) { visitCaseClause(stsCaseClause); } @@ -1154,7 +1149,6 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitStatement(stsStatement); indentDecrement(); - sb.append('\n'); return null; } @@ -1171,7 +1165,6 @@ public class StaticTSWriter extends StaticTSParserBaseVisitor { visitStatement(stsStatement); indentDecrement(); - sb.append('\n'); return null; } diff --git a/migrator/test/java/conditional_expression.java b/migrator/test/java/conditional_expression.java index 40b5fb2dcd5d5cb021a7342f730f831f18836727..2032053fc0283c446630eb570dd6b33641bfa73a 100644 --- a/migrator/test/java/conditional_expression.java +++ b/migrator/test/java/conditional_expression.java @@ -23,4 +23,4 @@ class ConditionalExpression { boolean someCondition = true; result = someCondition ? value1 : value2; } -} \ No newline at end of file +} diff --git a/migrator/test/java/for_statement.java.sts b/migrator/test/java/for_statement.java.sts index cbdfd1b456fe8e07858dd5f9fadb1ded7a1d7184..c1c6e6c92d8bfb14914affb58b4ff64d92c41f7d 100644 --- a/migrator/test/java/for_statement.java.sts +++ b/migrator/test/java/for_statement.java.sts @@ -17,19 +17,19 @@ package com.ohos.migrator.test.java; open class ForStatements { public static Test(): void { - for (; ; ) break; + for (; ; ) break; for (; ; ) { break; } for (let i : int = 0; ; ) { i++; - if (i == 2) continue; - if (i == 5) break; + if (i == 2) continue; + if (i == 5) break; } let a : int = 0; for (; a < 5; ) a++; for (; ; a--) { - if (a == 0) break; + if (a == 0) break; } for (let i : int = 0, j : int = 0; i < 5; i++, j++) { let k : int = i * j; @@ -40,9 +40,10 @@ open class ForStatements { } outerLoop: for (let i : int = 0; i < 5; i++) { innerLoop: for (let j : int = 0; j < 5; j++) { - if (j == 2) continue innerLoop; - if (i * j == 20) break outerLoop; + if (j == 2) continue innerLoop; + if (i * j == 20) break outerLoop; } } } } + diff --git a/migrator/test/java/method_invocation.java b/migrator/test/java/method_invocation.java index 55d81d8f8052b66d41979d43efd0bcff27a652ef..1c8887cb5902a8a3f613382f502f47f5a6b21f34 100644 --- a/migrator/test/java/method_invocation.java +++ b/migrator/test/java/method_invocation.java @@ -93,4 +93,4 @@ class Test3 { ColoredPoint2 cp = new ColoredPoint2(); //test(cp, cp); // Compile-time error } -} \ No newline at end of file +} diff --git a/migrator/test/java/switch_statement.java b/migrator/test/java/switch_statement.java new file mode 100644 index 0000000000000000000000000000000000000000..650307f9e5782df3f7d0ec0de6802488b2c11245 --- /dev/null +++ b/migrator/test/java/switch_statement.java @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +public class switch_statement { + + public static String ReturnFromSwitch(int id) { + switch (id) { + case 1: + return "First"; + case 2: + return "Second"; + default: + return "Unknown"; + } + } + + public static void CaseClausesVariations() { + int a = 0; + + // empty switch + switch (1) { + } + + // no default clause + switch (2) { + case 1: + a = 21; + break; + case 2: + a = 22; + break; + } + + // only default case + switch (3) { + default: + a = 31; + break; + } + + // case clause followed by default + switch (4) { + case 1: + a = 41; + break; + case 2: + break; + default: + a = 43; + break; + } + + // case clause following default clause + switch (5) { + default: + a = 51; + break; + case 1: + a = 52; + break; + case 2: + a = 53; + break; + } + + // case clauses before and after default clause + switch (6) { + case 1: + a = 61; + break; + default: + a = 62; + break; + case 2: + a = 63; + break; + } + + // Fall-through + switch (7) { + case 1: + case 2: + System.out.println("Falling through case 1 and case 2"); + break; + default: + System.out.println("Default case"); + break; + } + + // Fall-through + switch (8) { + case 1: + default: + System.out.println("Falling through both case and default clauses"); + break; + } + + // Fall-through + switch (9) { + case 1: + System.out.println("In case 1: Falling through to default case"); + default: + System.out.println("In default case"); + break; + case 2: + System.out.println("In case 2"); + break; + } + } + + public static void SwitchWithLocalDeclarations() { + int i = 10; + + // Local variable is referenced across several case clauses. + switch (i) { + case 0: + int q = 5; + int w = q; // This declaration is moved in front of switch. Initialization is turned into assignment. + int e; // This declaration is moved in front of switch. No initialization. + break; + default: + w = 10; + e = 20; + System.out.println(w + e); + break; + } + + // Multiple variables in single variable declaration list. + switch (i) { + case 0: + int q = 5, w, e = 10, r; // 'q' and 'r' are moved in front of switch. + int z = 20, x; // Both 'z' and 'x' declarations are left in this block. + System.out.println(q + e + z); + break; + default: + q = 2; + r = 4; + System.out.println(q + r); + break; + } + + // Block variable and hiding. + switch (i) { + case 1: + { + String localVar = "some value"; // 'String localVar' will hide the 'int localVar' in current block scope. + } + break; + case 2: + int localVar = 5; + break; + default: + localVar = 6; + break; + } + + // Local variable is initialized with expression that can cause side-effects. + // The order of evaluation of variable initializers must be preserved. + switch (i) { + case 0: + int q = i++, w = i++, e = i++; + break; + default: + q = 1; + e = 2; + break; + } + + // Variable 'k' is referenced from nested switch, though, it's still being used + // only within the case clause it was declared in. + switch (i) { + case 1: + int k = 10; + + switch (i) { + case 3: + k = 20; + break; + default: + break; + } + + break; + default: + break; + } + + // Switch with local class declaration + switch (i) { + case 1: + class LocalClass { + void M() { + System.out.println("LocalClass.M()"); + } + } + new LocalClass().M(); + break; + default: + break; + } + } + + enum Color { + Red, + Green, + Blue + } + + private static void SwitchWithEnumValues() { + Color color = Color.Green; + + switch (color) { + case Red: + System.out.println("Color is red"); + break; + case Blue: + System.out.println("Color is blue"); + break; + default: + System.out.println("Color is default"); + break; + } + } +} diff --git a/migrator/test/java/switch_statement.java.sts b/migrator/test/java/switch_statement.java.sts new file mode 100644 index 0000000000000000000000000000000000000000..0e10a1c587e9c8a4e8a74bd6a60ee71459f1c190 --- /dev/null +++ b/migrator/test/java/switch_statement.java.sts @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2022-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ohos.migrator.test.java; + +export open class switch_statement { + public static ReturnFromSwitch(id : int): String { + switch (id) { + case 1: + return "First"; + case 2: + return "Second"; + default: + return "Unknown"; + } + + } + public static CaseClausesVariations(): void { + let a : int = 0; + switch (1) { + } + + switch (2) { + case 1: + a = 21; + break; + case 2: + a = 22; + break; + } + + switch (3) { + default: + a = 31; + break; + } + + switch (4) { + case 1: + a = 41; + break; + case 2: + break; + default: + a = 43; + break; + } + + switch (5) { + default: + a = 51; + break; + case 1: + a = 52; + break; + case 2: + a = 53; + break; + } + + switch (6) { + case 1: + a = 61; + break; + default: + a = 62; + break; + case 2: + a = 63; + break; + } + + switch (7) { + case 1: + case 2: + System.out.println("Falling through case 1 and case 2"); + break; + default: + System.out.println("Default case"); + break; + } + + switch (8) { + case 1: + default: + System.out.println("Falling through both case and default clauses"); + break; + } + + switch (9) { + case 1: + System.out.println("In case 1: Falling through to default case"); + default: + System.out.println("In default case"); + break; + case 2: + System.out.println("In case 2"); + break; + } + + } + public static SwitchWithLocalDeclarations(): void { + let i : int = 10; + { + let w : int ; + let e : int ; + switch (i) { + case 0: + { + let q : int = 5; + w = q; + break; + } + default: + w = 10; + e = 20; + System.out.println(w + e); + break; + } + + } + { + let q : int ; + let r : int ; + switch (i) { + case 0: + { + q = 5; + let w : int ; + let e : int = 10; + let z : int = 20; + let x : int ; + System.out.println(q + e + z); + break; + } + default: + q = 2; + r = 4; + System.out.println(q + r); + break; + } + + } + { + let localVar : int ; + switch (i) { + case 1: + { + let localVar : String = "some value"; + } + break; + case 2: + localVar = 5; + break; + default: + localVar = 6; + break; + } + + } + { + let q : int ; + let e : int ; + switch (i) { + case 0: + { + q = i++; + let w : int = i++; + e = i++; + break; + } + default: + q = 1; + e = 2; + break; + } + + } + switch (i) { + case 1: + { + let k : int = 10; + switch (i) { + case 3: + k = 20; + break; + default: + break; + } + + break; + } + default: + break; + } + + switch (i) { + case 1: + { + open class LocalClass { + open M(): void { + System.out.println("LocalClass.M()"); + } + } + + new LocalClass().M(); + break; + } + default: + break; + } + + } + enum Color { + Red, + Green, + Blue + } + private static SwitchWithEnumValues(): void { + let color : Color = Color.Green; + switch (color) { + case Red: + System.out.println("Color is red"); + break; + case Blue: + System.out.println("Color is blue"); + break; + default: + System.out.println("Color is default"); + break; + } + + } +} +