From 7350e14e185f4479a17a73a17b5bc94e986d2404 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 26 Mar 2013 18:21:39 +0400 Subject: [PATCH] Fixed bug when class or trait declared early than its parent, traits and abstract classes which declared after doesn't translated #KT-3437 Fixed --- js/js.translator/js.translator.iml | 1 + .../ClassDeclarationTranslator.java | 63 ++++++++++--------- .../inheritance/cases/definitionOrder.kt | 9 ++- .../testFiles/trait/cases/definitionOrder.kt | 9 ++- 4 files changed, 52 insertions(+), 30 deletions(-) diff --git a/js/js.translator/js.translator.iml b/js/js.translator/js.translator.iml index a827f7758ae..3ec26a8e82c 100644 --- a/js/js.translator/js.translator.iml +++ b/js/js.translator/js.translator.iml @@ -10,6 +10,7 @@ + diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java index a26837b4bcb..03fb98ebfb1 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassDeclarationTranslator.java @@ -20,7 +20,6 @@ import com.google.dart.compiler.backend.js.ast.*; import com.intellij.openapi.util.Pair; import com.intellij.util.SmartList; import gnu.trove.THashMap; -import gnu.trove.TLinkable; import gnu.trove.TLinkableAdaptor; import gnu.trove.TLinkedList; import org.jetbrains.annotations.NotNull; @@ -29,19 +28,20 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.Modality; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.utils.DFS; import org.jetbrains.k2js.translate.LabelGenerator; import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.initializer.InitializerUtils; -import java.util.ArrayList; -import java.util.List; +import java.util.*; import static com.google.dart.compiler.backend.js.ast.JsVars.JsVar; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassDescriptorForType; import static org.jetbrains.k2js.translate.general.Translation.translateClassDeclaration; import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor; -import static org.jetbrains.k2js.translate.utils.ErrorReportingUtils.message; /** * Generates a big block where are all the classes(objects representing them) are created. @@ -55,6 +55,9 @@ public final class ClassDeclarationTranslator extends AbstractTranslator { private final TLinkedList openList = new TLinkedList(); private final List> finalList = new ArrayList>(); + @NotNull + private final ClassDescriptorToLabel classDescriptorToLabel = new ClassDescriptorToLabel(); + @NotNull private final JsFunction dummyFunction; @@ -70,7 +73,7 @@ public final class ClassDeclarationTranslator extends AbstractTranslator { declarationsObjectRef = declarationsObject.makeRef(); } - private final class OpenClassRefProvider implements ClassAliasingMap { + private final class ClassDescriptorToLabel implements ClassAliasingMap { @Override @Nullable public JsNameRef get(ClassDescriptor descriptor, ClassDescriptor referencedDescriptor) { @@ -80,20 +83,8 @@ public final class ClassDeclarationTranslator extends AbstractTranslator { return null; } - addAfter(item, openClassDescriptorToItem.get(referencedDescriptor)); return item.label; } - - private void addAfter(@NotNull FinalListItem item, @NotNull FinalListItem referencedItem) { - for (TLinkable link = item.getNext(); link != null; link = link.getNext()) { - if (link == referencedItem) { - return; - } - } - - openList.remove(referencedItem); - openList.addBefore((FinalListItem) item.getNext(), referencedItem); - } } private static class FinalListItem extends TLinkableAdaptor { @@ -101,8 +92,6 @@ public final class ClassDeclarationTranslator extends AbstractTranslator { private final JsNameRef label; private final JsNameRef qualifiedLabel; - private JsExpression translatedDeclaration; - private FinalListItem(JetClass declaration, JsNameRef label, JsNameRef qualifiedLabel) { this.declaration = declaration; this.label = label; @@ -134,17 +123,35 @@ public final class ClassDeclarationTranslator extends AbstractTranslator { } private void generateOpenClassDeclarations(@NotNull List vars, @NotNull List propertyInitializers) { - ClassAliasingMap classAliasingMap = new OpenClassRefProvider(); // first pass: set up list order - for (FinalListItem item : openList) { - item.translatedDeclaration = translateClassDeclaration(item.declaration, classAliasingMap, context()); - } + LinkedList sortedOpenClasses = + (LinkedList) DFS.topologicalOrder(openList, new DFS.Neighbors() { + @NotNull + @Override + public Iterable getNeighbors(FinalListItem current) { + TLinkedList parents = new TLinkedList(); + ClassDescriptor classDescriptor = getClassDescriptor(context().bindingContext(), current.declaration); + Collection superTypes = classDescriptor.getTypeConstructor().getSupertypes(); + + for (JetType type : superTypes) { + ClassDescriptor descriptor = getClassDescriptorForType(type); + FinalListItem item = openClassDescriptorToItem.get(descriptor); + if (item == null) { + continue; + } + + parents.add(item); + } + + return parents; + } + }); + // second pass: generate - for (FinalListItem item : openList) { - JsExpression translatedDeclaration = item.translatedDeclaration; - if (translatedDeclaration == null) { - throw new IllegalStateException(message(item.declaration, "Could not translate class declaration)")); - } + Iterator it = sortedOpenClasses.descendingIterator(); + while (it.hasNext()) { + FinalListItem item = it.next(); + JsExpression translatedDeclaration = translateClassDeclaration(item.declaration, classDescriptorToLabel, context()); generate(item, propertyInitializers, translatedDeclaration, vars); } } diff --git a/js/js.translator/testFiles/inheritance/cases/definitionOrder.kt b/js/js.translator/testFiles/inheritance/cases/definitionOrder.kt index 12e3f7b045c..10d2673d36e 100644 --- a/js/js.translator/testFiles/inheritance/cases/definitionOrder.kt +++ b/js/js.translator/testFiles/inheritance/cases/definitionOrder.kt @@ -24,7 +24,7 @@ open class B() : A() { } } -open class A() { +open class A() : G() { var order = "" { @@ -32,6 +32,13 @@ open class A() { } } +// KT-3437 +abstract class G : H() +abstract class K : H() +abstract class L +abstract class H : L() +abstract class Dummy + fun box() : Boolean { return (C().order == "ABC") && (D().order == "ABD") && (E().order == "AE") } \ No newline at end of file diff --git a/js/js.translator/testFiles/trait/cases/definitionOrder.kt b/js/js.translator/testFiles/trait/cases/definitionOrder.kt index b8508c7a9d0..f7dd2bbed6f 100644 --- a/js/js.translator/testFiles/trait/cases/definitionOrder.kt +++ b/js/js.translator/testFiles/trait/cases/definitionOrder.kt @@ -32,10 +32,17 @@ open class A() : F { } } -trait F { +trait F : G { fun bar() = "F" } +// KT-3437 +trait G : H +trait K : H +trait L +trait H : L +trait Dummy + fun box() : Boolean { return (C().order == "ABC") && (D().order == "ABD") && (E().order == "AE") && (C().bar() == "F") && (A().bar() == "F") } \ No newline at end of file