Fixed bug when class or trait declared early than its parent, traits and abstract classes which declared after doesn't translated

#KT-3437 Fixed
This commit is contained in:
Zalim Bashorov
2013-03-26 18:21:39 +04:00
parent ad4eeb3f8a
commit 7350e14e18
4 changed files with 52 additions and 30 deletions
+1
View File
@@ -10,6 +10,7 @@
<orderEntry type="module" module-name="frontend" />
<orderEntry type="library" name="js-libs" level="project" />
<orderEntry type="library" scope="PROVIDED" name="intellij-core" level="project" />
<orderEntry type="module" module-name="util" />
</component>
</module>
@@ -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<FinalListItem> openList = new TLinkedList<FinalListItem>();
private final List<Pair<JetClassOrObject, JsInvocation>> finalList = new ArrayList<Pair<JetClassOrObject, JsInvocation>>();
@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<JsVar> vars, @NotNull List<JsPropertyInitializer> propertyInitializers) {
ClassAliasingMap classAliasingMap = new OpenClassRefProvider();
// first pass: set up list order
for (FinalListItem item : openList) {
item.translatedDeclaration = translateClassDeclaration(item.declaration, classAliasingMap, context());
}
LinkedList<FinalListItem> sortedOpenClasses =
(LinkedList<FinalListItem>) DFS.topologicalOrder(openList, new DFS.Neighbors<FinalListItem>() {
@NotNull
@Override
public Iterable<FinalListItem> getNeighbors(FinalListItem current) {
TLinkedList<FinalListItem> parents = new TLinkedList<FinalListItem>();
ClassDescriptor classDescriptor = getClassDescriptor(context().bindingContext(), current.declaration);
Collection<JetType> 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<FinalListItem> it = sortedOpenClasses.descendingIterator();
while (it.hasNext()) {
FinalListItem item = it.next();
JsExpression translatedDeclaration = translateClassDeclaration(item.declaration, classDescriptorToLabel, context());
generate(item, propertyInitializers, translatedDeclaration, vars);
}
}
@@ -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")
}
@@ -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")
}