Added support for passing parameters to ancestor constructor. Added a test.

This commit is contained in:
Pavel Talanov
2011-11-15 22:22:00 +04:00
parent 34d649938b
commit 24d1cb1a1f
6 changed files with 64 additions and 28 deletions
@@ -12,7 +12,6 @@ import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@@ -130,7 +129,7 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
@NotNull @NotNull
public JsNode visitCallExpression(JetCallExpression expression, TranslationContext context) { public JsNode visitCallExpression(JetCallExpression expression, TranslationContext context) {
JsExpression callee = getCallee(expression, context); JsExpression callee = getCallee(expression, context);
List<JsExpression> arguments = generateArgumentList(expression.getValueArguments(), context); List<JsExpression> arguments = translateArgumentList(expression.getValueArguments(), context);
if (isConstructorInvocation(expression, context)) { if (isConstructorInvocation(expression, context)) {
JsNew constructorCall = new JsNew(callee); JsNew constructorCall = new JsNew(callee);
constructorCall.setArguments(arguments); constructorCall.setArguments(arguments);
@@ -160,25 +159,6 @@ public final class ExpressionVisitor extends TranslatorVisitor<JsNode> {
return AstUtil.convertToExpression(jsCallee); return AstUtil.convertToExpression(jsCallee);
} }
@NotNull
private List<JsExpression> generateArgumentList(@NotNull List<? extends ValueArgument> jetArguments,
@NotNull TranslationContext context) {
List<JsExpression> jsArguments = new ArrayList<JsExpression>();
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 @Override
@NotNull @NotNull
public JsNode visitIfExpression(@NotNull JetIfExpression expression, @NotNull TranslationContext context) { public JsNode visitIfExpression(@NotNull JetIfExpression expression, @NotNull TranslationContext context) {
@@ -55,12 +55,32 @@ public class InitializerVisitor extends TranslatorVisitor<List<JsStatement>> {
List<JsStatement> result = new ArrayList<JsStatement>(); List<JsStatement> result = new ArrayList<JsStatement>();
if (BindingUtils.hasAncestor(context.bindingContext(), classDeclaration)) { if (BindingUtils.hasAncestor(context.bindingContext(), classDeclaration)) {
JsName superMethodName = initializerMethodScope.declareName(Namer.SUPER_METHOD_NAME); JsName superMethodName = initializerMethodScope.declareName(Namer.SUPER_METHOD_NAME);
List<JsExpression> arguments = translateArguments(classDeclaration, context);
result.add(AstUtil.convertToStatement result.add(AstUtil.convertToStatement
(AstUtil.newInvocation(AstUtil.thisQualifiedReference(superMethodName)))); (AstUtil.newInvocation(AstUtil.thisQualifiedReference(superMethodName), arguments)));
} }
return result; return result;
} }
@NotNull
private List<JsExpression> 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 @Override
@NotNull @NotNull
@@ -5,10 +5,10 @@ import com.google.dart.compiler.backend.js.ast.JsName;
import com.google.dart.compiler.util.AstUtil; import com.google.dart.compiler.util.AstUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetProperty; import java.util.ArrayList;
import org.jetbrains.jet.lang.psi.JetVisitor; import java.util.List;
/** /**
* @author Talanov Pavel * @author Talanov Pavel
@@ -50,4 +50,23 @@ public class TranslatorVisitor<T> extends JetVisitor<T, TranslationContext> {
} }
return jsInitExpression; return jsInitExpression;
} }
@NotNull
protected List<JsExpression> translateArgumentList(@NotNull List<? extends ValueArgument> jetArguments,
@NotNull TranslationContext context) {
List<JsExpression> jsArguments = new ArrayList<JsExpression>();
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));
}
} }
@@ -33,6 +33,11 @@ public final class ClassInheritanceTest extends AbstractClassTest {
public void complexInitializationOrder() throws Exception { public void complexInitializationOrder() throws Exception {
testFooBoxIsTrue("complexInitializationOrder.kt"); testFooBoxIsTrue("complexInitializationOrder.kt");
} }
@Test
public void valuePassedToAncestorConstructor() throws Exception {
testFooBoxIsTrue("valuePassedToAncestorConstructor.kt");
}
} }
@@ -1,10 +1,10 @@
namespace foo namespace foo
open class C { open class C() {
open fun f(): Any = "C f" open fun f(): Any = "C f"
} }
class D() : C { class D() : C() {
override fun f(): String = "D f" override fun f(): String = "D f"
} }
@@ -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)
}