diff --git a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java index af746d54e44..0b010f9d22e 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java @@ -393,4 +393,11 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull TranslationContext context) { return ForTranslator.translate(expression, context); } + + @Override + @NotNull + public JsNode visitTryExpression(@NotNull JetTryExpression expression, + @NotNull TranslationContext context) { + return TryTranslator.translate(expression, context); + } } diff --git a/translator/src/org/jetbrains/k2js/translate/expression/TryTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/TryTranslator.java new file mode 100644 index 00000000000..eb9834d061c --- /dev/null +++ b/translator/src/org/jetbrains/k2js/translate/expression/TryTranslator.java @@ -0,0 +1,90 @@ +package org.jetbrains.k2js.translate.expression; + +import com.google.dart.compiler.backend.js.ast.JsBlock; +import com.google.dart.compiler.backend.js.ast.JsCatch; +import com.google.dart.compiler.backend.js.ast.JsName; +import com.google.dart.compiler.backend.js.ast.JsTry; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.k2js.translate.context.TranslationContext; +import org.jetbrains.k2js.translate.general.AbstractTranslator; +import org.jetbrains.k2js.translate.general.Translation; + +import java.util.ArrayList; +import java.util.List; + +import static com.google.dart.compiler.util.AstUtil.convertToBlock; + +/** + * @author Talanov Pavel + */ +public final class TryTranslator extends AbstractTranslator { + + @NotNull + public static JsTry translate(@NotNull JetTryExpression expression, + @NotNull TranslationContext context) { + return (new TryTranslator(expression, context)).translate(); + } + + @NotNull + private final JetTryExpression expression; + + private TryTranslator(@NotNull JetTryExpression expression, + @NotNull TranslationContext context) { + super(context); + this.expression = expression; + } + + private JsTry translate() { + JsTry result = new JsTry(); + result.setTryBlock(translateTryBlock()); + result.setFinallyBlock(translateFinallyBlock()); + result.getCatches().addAll(translateCatches()); + return result; + } + + @Nullable + private JsBlock translateFinallyBlock() { + JetFinallySection finallyBlock = expression.getFinallyBlock(); + if (finallyBlock == null) return null; + + return convertToBlock(Translation.translateAsStatement(finallyBlock.getFinalExpression(), context())); + } + + @NotNull + private JsBlock translateTryBlock() { + return convertToBlock(Translation.translateAsStatement(expression.getTryBlock(), context())); + } + + + @NotNull + private List translateCatches() { + List result = new ArrayList(); + for (JetCatchClause catchClause : expression.getCatchClauses()) { + result.add(translateCatchClause(catchClause)); + } + return result; + } + + @NotNull + private JsCatch translateCatchClause(@NotNull JetCatchClause catchClause) { + JetParameter catchParameter = catchClause.getCatchParameter(); + assert catchParameter != null : "Valid catch must have a parameter."; + + JsName parameterName = context().declareLocalVariable(catchParameter); + JsCatch result = new JsCatch(context().jsScope(), parameterName.getIdent()); + result.setBody(translateCatchBody(catchClause)); + return result; + } + + @NotNull + private JsBlock translateCatchBody(@NotNull JetCatchClause catchClause) { + JetExpression catchBody = catchClause.getCatchBody(); + if (catchBody == null) { + return convertToBlock(program().getEmptyStmt()); + } + return convertToBlock(Translation.translateAsStatement(catchBody, context())); + } + +} diff --git a/translator/src/org/jetbrains/k2js/translate/general/TranslatorVisitor.java b/translator/src/org/jetbrains/k2js/translate/general/TranslatorVisitor.java index 22fb2517f4f..9e1880b947e 100644 --- a/translator/src/org/jetbrains/k2js/translate/general/TranslatorVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/general/TranslatorVisitor.java @@ -15,7 +15,7 @@ public class TranslatorVisitor extends JetVisitor { @Override @NotNull public T visitJetElement(JetElement expression, TranslationContext context) { - throw new RuntimeException("Unsupported expression encountered:" + expression.toString()); + throw new UnsupportedOperationException("Unsupported expression encountered:" + expression.toString()); } } diff --git a/translator/test/org/jetbrains/k2js/test/SystemTest.java b/translator/test/org/jetbrains/k2js/test/SystemTest.java index 38ad9020589..83589966d48 100644 --- a/translator/test/org/jetbrains/k2js/test/SystemTest.java +++ b/translator/test/org/jetbrains/k2js/test/SystemTest.java @@ -42,10 +42,21 @@ public final class SystemTest extends JavaClassesTest { checkOutput("ifAsExpression.kt", "20\n", "10", "20"); } + @Test + public void objectOrientedHello() throws Exception { + checkOutput("objectOrientedHello.kt", "Hello, Pavel!\n", "Pavel"); + } + @Test public void multiLanguageHello() throws Exception { checkOutput("multiLanguageHello.kt", "Salut!\n", "FR"); } + @Test + public void nullChecks() throws Exception { + checkOutput("nullChecks.kt", "No number supplied"); + checkOutput("nullChecks.kt", "6", "2", "3"); + } + } diff --git a/translator/testFiles/java/system/cases/nullChecks.kt b/translator/testFiles/java/system/cases/nullChecks.kt new file mode 100644 index 00000000000..ebfac5371a5 --- /dev/null +++ b/translator/testFiles/java/system/cases/nullChecks.kt @@ -0,0 +1,23 @@ +// Return null if str does not hold a number +fun parseInt(str : String) : Int? { + try{ + return Integer.parseInt(str) + } catch (e: NumberFormatException) { + System.out?.println("One of argument isn't Int") + } + return null +} + +fun main(args : Array) { + if (args.size < 2) { + System.out?.print("No number supplied"); + } else { + val x = parseInt(args[0]) + val y = parseInt(args[1]) + + // We cannot say 'x * y' now because they may hold nulls + if (x != null && y != null) { + System.out?.print(x * y) // Now we can + } + } +} diff --git a/translator/testFiles/java/system/cases/objectOrientedHello.kt b/translator/testFiles/java/system/cases/objectOrientedHello.kt new file mode 100644 index 00000000000..b50d54bbb9d --- /dev/null +++ b/translator/testFiles/java/system/cases/objectOrientedHello.kt @@ -0,0 +1,10 @@ +class Greeter(name : String) { + val name = name + fun greet() { + System.out?.println("Hello, ${name}!"); + } +} + +fun main(args : Array) { + Greeter(args[0]).greet() +} \ No newline at end of file