JS backend: fix order class and trait in list supertypes

This commit is contained in:
Erokhin Stanislav
2013-08-22 20:30:37 +04:00
parent 430b60d979
commit fd2caf5acf
2 changed files with 35 additions and 44 deletions
@@ -35,10 +35,7 @@ import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.FilteringScope; import org.jetbrains.jet.lang.resolve.scopes.FilteringScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.DescriptorSubstitutor; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.renderer.DescriptorRenderer;
@@ -300,7 +297,7 @@ public class DescriptorUtils {
List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>(); List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
for (JetType type : superclassTypes) { for (JetType type : superclassTypes) {
ClassDescriptor result = getClassDescriptorForType(type); ClassDescriptor result = getClassDescriptorForType(type);
if (isNotAny(result)) { if (!isAny(result)) {
superClassDescriptors.add(result); superClassDescriptors.add(result);
} }
} }
@@ -309,15 +306,20 @@ public class DescriptorUtils {
@NotNull @NotNull
public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) { public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) {
return getClassDescriptorForTypeConstructor(type.getConstructor());
}
@NotNull
public static ClassDescriptor getClassDescriptorForTypeConstructor(@NotNull TypeConstructor typeConstructor) {
DeclarationDescriptor superClassDescriptor = DeclarationDescriptor superClassDescriptor =
type.getConstructor().getDeclarationDescriptor(); typeConstructor.getDeclarationDescriptor();
assert superClassDescriptor instanceof ClassDescriptor assert superClassDescriptor instanceof ClassDescriptor
: "Superclass descriptor of a type should be of type ClassDescriptor"; : "Superclass descriptor of a type should be of type ClassDescriptor";
return (ClassDescriptor)superClassDescriptor; return (ClassDescriptor)superClassDescriptor;
} }
public static boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) { public static boolean isAny(@NotNull DeclarationDescriptor superClassDescriptor) {
return !superClassDescriptor.equals(KotlinBuiltIns.getInstance().getAny()); return superClassDescriptor.equals(KotlinBuiltIns.getInstance().getAny());
} }
public static boolean inStaticContext(@NotNull DeclarationDescriptor descriptor) { public static boolean inStaticContext(@NotNull DeclarationDescriptor descriptor) {
@@ -29,21 +29,18 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.psi.JetParameter;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeConstructor;
import org.jetbrains.k2js.translate.LabelGenerator; import org.jetbrains.k2js.translate.LabelGenerator;
import org.jetbrains.k2js.translate.context.Namer; import org.jetbrains.k2js.translate.context.Namer;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator;
import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator; import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
import org.jetbrains.k2js.translate.utils.AnnotationsUtils;
import org.jetbrains.k2js.translate.utils.JsAstUtils; import org.jetbrains.k2js.translate.utils.JsAstUtils;
import java.util.ArrayList; import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassDescriptorForType; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isNotAny; import static org.jetbrains.jet.lang.types.TypeUtils.topologicallySortSuperclassesAndRecordAllInstances;
import static org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator.createPlace; import static org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator.createPlace;
import static org.jetbrains.k2js.translate.initializer.InitializerUtils.createPropertyInitializer; import static org.jetbrains.k2js.translate.initializer.InitializerUtils.createPropertyInitializer;
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor; import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
@@ -257,40 +254,32 @@ public final class ClassTranslator extends AbstractTranslator {
if (supertypes.isEmpty()) { if (supertypes.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} }
if (supertypes.size() == 1) {
JetType type = supertypes.iterator().next();
ClassDescriptor supertypeDescriptor = getClassDescriptorForType(type);
if (isAny(supertypeDescriptor)) {
return Collections.emptyList();
}
return Collections.<JsExpression>singletonList(getClassReference(supertypeDescriptor));
}
JsExpression base = null; Set<TypeConstructor> supertypeConstructors = new HashSet<TypeConstructor>();
List<JsExpression> list = null;
for (JetType type : supertypes) { for (JetType type : supertypes) {
ClassDescriptor result = getClassDescriptorForType(type); supertypeConstructors.add(type.getConstructor());
if (isNotAny(result) && !AnnotationsUtils.isNativeObject(result)) { }
switch (result.getKind()) { List<TypeConstructor> sortedAllSuperTypes = topologicallySortSuperclassesAndRecordAllInstances(descriptor.getDefaultType(),
case CLASS: new HashMap<TypeConstructor, Set<JetType>>(),
base = getClassReference(result); new HashSet<TypeConstructor>());
break; List<JsExpression> supertypesRefs = new ArrayList<JsExpression>();
case TRAIT: for (TypeConstructor typeConstructor : sortedAllSuperTypes) {
if (list == null) { if (supertypeConstructors.contains(typeConstructor)) {
list = new ArrayList<JsExpression>(); ClassDescriptor supertypeDescriptor = getClassDescriptorForTypeConstructor(typeConstructor);
} if (!isAny(supertypeDescriptor)) {
list.add(getClassReference(result)); supertypesRefs.add(getClassReference(supertypeDescriptor));
break;
case ENUM_CLASS:
base = getClassReference(result);
break;
default:
throw new UnsupportedOperationException("unsupported super class kind " + result.getKind().name());
} }
} }
} }
return supertypesRefs;
if (list == null) {
return base == null ? Collections.<JsExpression>emptyList() : Collections.singletonList(base);
}
else if (base != null) {
list.add(0, base);
}
return list;
} }
@NotNull @NotNull