JS backend: use jet.Iterable and jet.Any as "fake" classes.
This commit is contained in:
@@ -75,6 +75,9 @@ public final class ClassInheritanceTest extends SingleFileTranslationTest {
|
||||
public void testKt3499() throws Exception {
|
||||
fooBoxTest();
|
||||
}
|
||||
public void testFromFakeClasses() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ import static org.jetbrains.k2js.translate.initializer.InitializerUtils.createCl
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getContainingClass;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getSupertypesWithoutFakes;
|
||||
import static org.jetbrains.k2js.translate.utils.PsiUtils.getPrimaryConstructorParameters;
|
||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.simpleReturnFunction;
|
||||
|
||||
@@ -220,16 +221,13 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
|
||||
@NotNull
|
||||
private List<JsExpression> getSupertypesNameReferences() {
|
||||
Collection<JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
|
||||
List<JetType> supertypes = getSupertypesWithoutFakes(descriptor);
|
||||
if (supertypes.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (supertypes.size() == 1) {
|
||||
JetType type = supertypes.iterator().next();
|
||||
JetType type = supertypes.get(0);
|
||||
ClassDescriptor supertypeDescriptor = getClassDescriptorForType(type);
|
||||
if (isAny(supertypeDescriptor)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return Collections.<JsExpression>singletonList(getClassReference(supertypeDescriptor));
|
||||
}
|
||||
|
||||
@@ -244,9 +242,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
||||
for (TypeConstructor typeConstructor : sortedAllSuperTypes) {
|
||||
if (supertypeConstructors.contains(typeConstructor)) {
|
||||
ClassDescriptor supertypeDescriptor = getClassDescriptorForTypeConstructor(typeConstructor);
|
||||
if (!isAny(supertypeDescriptor)) {
|
||||
supertypesRefs.add(getClassReference(supertypeDescriptor));
|
||||
}
|
||||
supertypesRefs.add(getClassReference(supertypeDescriptor));
|
||||
}
|
||||
}
|
||||
return supertypesRefs;
|
||||
|
||||
+3
-3
@@ -35,12 +35,12 @@ import org.jetbrains.k2js.translate.initializer.ClassInitializerTranslator;
|
||||
import org.jetbrains.k2js.translate.utils.BindingUtils;
|
||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.k2js.translate.initializer.InitializerUtils.createClassObjectInitializer;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getClassDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
||||
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getSupertypesWithoutFakes;
|
||||
|
||||
public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
||||
@KotlinSignature("val result: MutableList<JsPropertyInitializer>")
|
||||
@@ -75,12 +75,12 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
||||
public Void visitEnumEntry(@NotNull JetEnumEntry enumEntry, TranslationContext data) {
|
||||
JsExpression jsEnumEntryCreation;
|
||||
ClassDescriptor descriptor = getClassDescriptor(data.bindingContext(), enumEntry);
|
||||
Collection<JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
|
||||
List<JetType> supertypes = getSupertypesWithoutFakes(descriptor);
|
||||
if (enumEntry.getBody() != null || supertypes.size() > 1) {
|
||||
jsEnumEntryCreation = ClassTranslator.generateClassCreation(enumEntry, descriptor, data);
|
||||
} else {
|
||||
assert supertypes.size() == 1 : "Simple Enum entry must have one supertype";
|
||||
jsEnumEntryCreation = new ClassInitializerTranslator(enumEntry, data).generateEnumEntryInstanceCreation(supertypes.iterator().next());
|
||||
jsEnumEntryCreation = new ClassInitializerTranslator(enumEntry, data).generateEnumEntryInstanceCreation(supertypes.get(0));
|
||||
}
|
||||
enumEntryList.add(new JsPropertyInitializer(data.getNameForDescriptor(descriptor).makeRef(), jsEnumEntryCreation));
|
||||
return null;
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.jetbrains.k2js.translate.utils;
|
||||
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
@@ -29,13 +31,19 @@ import org.jetbrains.jet.lang.types.expressions.OperatorConventions;
|
||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getSuperclassDescriptors;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFQName;
|
||||
|
||||
public final class JsDescriptorUtils {
|
||||
// TODO: maybe we should use external annotations or something else.
|
||||
private static final Set<String> FAKE_CLASSES = ContainerUtil.immutableSet(
|
||||
getFQName(KotlinBuiltIns.getInstance().getAny()).toSafe().asString(),
|
||||
"jet.Iterable"
|
||||
);
|
||||
|
||||
private JsDescriptorUtils() {
|
||||
}
|
||||
@@ -67,6 +75,18 @@ public final class JsDescriptorUtils {
|
||||
return findAncestorClass(getSuperclassDescriptors(classDescriptor));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<JetType> getSupertypesWithoutFakes(ClassDescriptor descriptor) {
|
||||
Collection<JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
|
||||
return ContainerUtil.filter(supertypes, new Condition<JetType>() {
|
||||
@Override
|
||||
public boolean value(JetType type) {
|
||||
ClassDescriptor classDescriptor = getClassDescriptorForType(type);
|
||||
return !FAKE_CLASSES.contains(getFQName(classDescriptor).toSafe().asString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static DeclarationDescriptor getContainingDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||
DeclarationDescriptor containing = descriptor.getContainingDeclaration();
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package foo
|
||||
|
||||
class FromAny: Any()
|
||||
|
||||
class FromItrable(val n: Int): Iterable<Int> {
|
||||
override fun iterator() = object: Iterator<Int> {
|
||||
var i = 0
|
||||
override fun next() = i++
|
||||
override fun hasNext() = i < n
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Iterable<T>.stringify(): String {
|
||||
var s = ""
|
||||
for (i in this) s += i
|
||||
return s
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = FromAny()
|
||||
val it = FromItrable(3)
|
||||
|
||||
val s = it.stringify()
|
||||
if (s != "012") return "s /*$s*/ != 012"
|
||||
|
||||
var ao = object : Any() {}
|
||||
var ito = object : Iterable<Int> {
|
||||
override public fun iterator() = object: Iterator<Int> {
|
||||
var i = 0
|
||||
override fun next(): Int {
|
||||
var r = i
|
||||
i += 2
|
||||
return r
|
||||
}
|
||||
override fun hasNext() = i < 9
|
||||
}
|
||||
}
|
||||
|
||||
val so = ito.stringify()
|
||||
if (so != "02468") return "so /*$so*/ != 02468"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
Reference in New Issue
Block a user