From 24d1cb1a1fa6078e1a822e85527a6bf30d8c6949 Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Tue, 15 Nov 2011 22:22:00 +0400 Subject: [PATCH] Added support for passing parameters to ancestor constructor. Added a test. --- .../k2js/translate/ExpressionVisitor.java | 22 +-------------- .../k2js/translate/InitializerVisitor.java | 22 ++++++++++++++- .../k2js/translate/TranslatorVisitor.java | 27 ++++++++++++++++--- .../k2js/test/ClassInheritanceTest.java | 5 ++++ .../inheritance/cases/methodOverride.kt | 4 +-- .../cases/valuePassedToAncestorConstructor.kt | 12 +++++++++ 6 files changed, 64 insertions(+), 28 deletions(-) create mode 100644 translator/testFiles/inheritance/cases/valuePassedToAncestorConstructor.kt diff --git a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java index c8d4c0a2179..b9e58407427 100644 --- a/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/ExpressionVisitor.java @@ -12,7 +12,6 @@ import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lexer.JetTokens; -import java.util.ArrayList; import java.util.List; /** @@ -130,7 +129,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { @NotNull public JsNode visitCallExpression(JetCallExpression expression, TranslationContext context) { JsExpression callee = getCallee(expression, context); - List arguments = generateArgumentList(expression.getValueArguments(), context); + List arguments = translateArgumentList(expression.getValueArguments(), context); if (isConstructorInvocation(expression, context)) { JsNew constructorCall = new JsNew(callee); constructorCall.setArguments(arguments); @@ -160,25 +159,6 @@ public final class ExpressionVisitor extends TranslatorVisitor { return AstUtil.convertToExpression(jsCallee); } - @NotNull - private List generateArgumentList(@NotNull List jetArguments, - @NotNull TranslationContext context) { - List jsArguments = new ArrayList(); - for (ValueArgument argument : jetArguments) { - jsArguments.add(translateArgument(context, argument)); - } - return jsArguments; - } - - @NotNull - private JsExpression translateArgument(@NotNull TranslationContext context, @NotNull ValueArgument argument) { - JetExpression jetExpression = argument.getArgumentExpression(); - if (jetExpression == null) { - throw new AssertionError("Argument with no expression encountered!"); - } - return AstUtil.convertToExpression(jetExpression.accept(this, context)); - } - @Override @NotNull public JsNode visitIfExpression(@NotNull JetIfExpression expression, @NotNull TranslationContext context) { diff --git a/translator/src/org/jetbrains/k2js/translate/InitializerVisitor.java b/translator/src/org/jetbrains/k2js/translate/InitializerVisitor.java index a58867ffb57..b4c69297a3c 100644 --- a/translator/src/org/jetbrains/k2js/translate/InitializerVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/InitializerVisitor.java @@ -55,12 +55,32 @@ public class InitializerVisitor extends TranslatorVisitor> { List result = new ArrayList(); if (BindingUtils.hasAncestor(context.bindingContext(), classDeclaration)) { JsName superMethodName = initializerMethodScope.declareName(Namer.SUPER_METHOD_NAME); + List arguments = translateArguments(classDeclaration, context); result.add(AstUtil.convertToStatement - (AstUtil.newInvocation(AstUtil.thisQualifiedReference(superMethodName)))); + (AstUtil.newInvocation(AstUtil.thisQualifiedReference(superMethodName), arguments))); } return result; } + @NotNull + private List translateArguments(@NotNull JetClass classDeclaration, + @NotNull TranslationContext context) { + JetDelegatorToSuperCall superCall = getSuperCall(classDeclaration); + return translateArgumentList(superCall.getValueArguments(), context); + } + + @NotNull + private JetDelegatorToSuperCall getSuperCall(@NotNull JetClass classDeclaration) { + JetDelegatorToSuperCall result = null; + for (JetDelegationSpecifier specifier : classDeclaration.getDelegationSpecifiers()) { + if (specifier instanceof JetDelegatorToSuperCall) { + result = (JetDelegatorToSuperCall) specifier; + } + } + assert result != null : "Class must call ancestor's constructor."; + return result; + } + @Override @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java b/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java index b3b9f9d29b4..aacc912ce4f 100644 --- a/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java +++ b/translator/src/org/jetbrains/k2js/translate/TranslatorVisitor.java @@ -5,10 +5,10 @@ import com.google.dart.compiler.backend.js.ast.JsName; import com.google.dart.compiler.util.AstUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.psi.JetElement; -import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.jet.lang.psi.JetProperty; -import org.jetbrains.jet.lang.psi.JetVisitor; +import org.jetbrains.jet.lang.psi.*; + +import java.util.ArrayList; +import java.util.List; /** * @author Talanov Pavel @@ -50,4 +50,23 @@ public class TranslatorVisitor extends JetVisitor { } return jsInitExpression; } + + @NotNull + protected List translateArgumentList(@NotNull List jetArguments, + @NotNull TranslationContext context) { + List jsArguments = new ArrayList(); + for (ValueArgument argument : jetArguments) { + jsArguments.add(translateArgument(context, argument)); + } + return jsArguments; + } + + @NotNull + private JsExpression translateArgument(@NotNull TranslationContext context, @NotNull ValueArgument argument) { + JetExpression jetExpression = argument.getArgumentExpression(); + if (jetExpression == null) { + throw new AssertionError("Argument with no expression encountered!"); + } + return AstUtil.convertToExpression(Translation.translateExpression(jetExpression, context)); + } } diff --git a/translator/test/org/jetbrains/k2js/test/ClassInheritanceTest.java b/translator/test/org/jetbrains/k2js/test/ClassInheritanceTest.java index 0a5a830d73f..23b0b80cf1e 100644 --- a/translator/test/org/jetbrains/k2js/test/ClassInheritanceTest.java +++ b/translator/test/org/jetbrains/k2js/test/ClassInheritanceTest.java @@ -33,6 +33,11 @@ public final class ClassInheritanceTest extends AbstractClassTest { public void complexInitializationOrder() throws Exception { testFooBoxIsTrue("complexInitializationOrder.kt"); } + + @Test + public void valuePassedToAncestorConstructor() throws Exception { + testFooBoxIsTrue("valuePassedToAncestorConstructor.kt"); + } } diff --git a/translator/testFiles/inheritance/cases/methodOverride.kt b/translator/testFiles/inheritance/cases/methodOverride.kt index 82fddf73760..9f257be4a32 100644 --- a/translator/testFiles/inheritance/cases/methodOverride.kt +++ b/translator/testFiles/inheritance/cases/methodOverride.kt @@ -1,10 +1,10 @@ namespace foo -open class C { +open class C() { open fun f(): Any = "C f" } -class D() : C { +class D() : C() { override fun f(): String = "D f" } diff --git a/translator/testFiles/inheritance/cases/valuePassedToAncestorConstructor.kt b/translator/testFiles/inheritance/cases/valuePassedToAncestorConstructor.kt new file mode 100644 index 00000000000..7999a3ca4f7 --- /dev/null +++ b/translator/testFiles/inheritance/cases/valuePassedToAncestorConstructor.kt @@ -0,0 +1,12 @@ +namespace foo + +open class C(a : Int) { + val b = a +} + +class D(c : Int) : C(c + 2) { +} + +fun box(): Boolean { + return (D(0).b == 2) +} \ No newline at end of file