Found and solved a problem which caused only one ancestor's constructor to be called. Added "super_init" method generation to InitializerVisitor. Worked on KotlinJsLib to solve this issue. This solution should evolve in the future.

This commit is contained in:
Pavel Talanov
2011-11-15 21:05:54 +04:00
parent a120125e5a
commit 17e41e627d
9 changed files with 74 additions and 8 deletions
@@ -262,4 +262,10 @@ public class AstUtil {
result.setQualifier(new JsThisRef());
return result;
}
public static JsBlock newBlock(List<JsStatement> statements) {
JsBlock result = new JsBlock();
result.setStatements(statements);
return result;
}
}
@@ -101,6 +101,10 @@ public final class BindingUtils {
return superClassDescriptors;
}
static public boolean hasAncestor(@NotNull BindingContext context, @NotNull JetClass classDeclaration) {
return !getSuperclassDescriptors(context, classDeclaration).isEmpty();
}
static public boolean isStatement(@NotNull BindingContext context, @NotNull JetExpression expression) {
return context.get(BindingContext.STATEMENT, expression);
}
@@ -73,6 +73,7 @@ public final class ClassTranslator extends AbstractTranslator {
return new JsObjectLiteral(propertyList);
}
// TODO: names are inconsistent
@NotNull
private JsPropertyInitializer generateInitializeMethod(@NotNull JetClass classDeclaration) {
JsPropertyInitializer initializer = new JsPropertyInitializer();
@@ -43,10 +43,22 @@ public class InitializerVisitor extends TranslatorVisitor<List<JsStatement>> {
@NotNull
private JsBlock generateInitializerMethodBody(@NotNull JetClass classDeclaration,
@NotNull TranslationContext context) {
List<JsStatement> initializerStatements = classDeclaration.accept(this, context);
JsBlock block = new JsBlock();
block.setStatements(initializerStatements);
return block;
List<JsStatement> initializerStatements = generateCallToSuperMethod(classDeclaration, context);
initializerStatements.addAll(classDeclaration.accept(this, context));
return AstUtil.newBlock(initializerStatements);
}
@NotNull
private List<JsStatement> generateCallToSuperMethod(@NotNull JetClass classDeclaration,
@NotNull TranslationContext context) {
List<JsStatement> result = new ArrayList<JsStatement>();
if (BindingUtils.hasAncestor(context.bindingContext(), classDeclaration)) {
JsName superMethodName = initializerMethodScope.declareName(Namer.SUPER_METHOD_NAME);
result.add(AstUtil.convertToStatement
(AstUtil.newInvocation(AstUtil.thisQualifiedReference(superMethodName))));
}
return result;
}
@@ -22,6 +22,7 @@ public final class Namer {
private static final String SETTER_PREFIX = "set_";
private static final String GETTER_PREFIX = "get_";
private static final String BACKING_FIELD_PREFIX = "$";
public static final String SUPER_METHOD_NAME = "super_init";
// public static final String DEFAULT_SETTER_PARAM_NAME = "val";
public static String getClassObjectName() {
@@ -37,7 +37,7 @@ public final class OperatorTable {
binaryOperatorsMap.put(JetTokens.GTEQ, JsBinaryOperator.GTE);
binaryOperatorsMap.put(JetTokens.LT, JsBinaryOperator.LT);
binaryOperatorsMap.put(JetTokens.LTEQ, JsBinaryOperator.LTE);
binaryOperatorsMap.put(JetTokens.EQEQ, JsBinaryOperator.EQ);
binaryOperatorsMap.put(JetTokens.EQEQ, JsBinaryOperator.REF_EQ);
binaryOperatorsMap.put(JetTokens.ANDAND, JsBinaryOperator.AND);
binaryOperatorsMap.put(JetTokens.EXCLEQ, JsBinaryOperator.NEQ);
binaryOperatorsMap.put(JetTokens.PERC, JsBinaryOperator.MOD);
@@ -23,6 +23,11 @@ public final class ClassInheritanceTest extends AbstractClassTest {
public void methodOverride() throws Exception {
testFooBoxIsTrue("methodOverride.kt");
}
@Test
public void initializationOrder() throws Exception {
testFooBoxIsTrue("initializationOrder.kt");
}
}
@@ -0,0 +1,26 @@
namespace foo
open class A() {
var order = ""
{
order = order + "A"
}
}
open class B() : A() {
{
order = order + "B"
}
}
class C() : B() {
{
order = order + "C"
}
}
fun box() : Boolean {
return (C().order == "ABC") && (B().order == "AB") && (A().order == "A")
}
+14 -3
View File
@@ -24,9 +24,7 @@ var Class = (function() {
parent = properties.shift();
function klass() {
if (parent != null) {
parent.prototype.initialize.apply(this)
}
this.initializing = klass;
this.initialize.apply(this, arguments);
}
@@ -40,6 +38,19 @@ var Class = (function() {
parent.subclasses.push(klass);
}
if (parent != null) {
klass.addMethods(
{
'super_init' : function () {
//if (this.initializing != null) {
this.initializing = this.initializing.superclass;
this.initializing.prototype.initialize.apply(this, arguments)
// }
}
});
}
for (var i = 0, length = properties.length; i < length; i++)
klass.addMethods(properties[i]);