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 {
|
public void testKt3499() throws Exception {
|
||||||
fooBoxTest();
|
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.getClassDescriptor;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getPropertyDescriptorForConstructorParameter;
|
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.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.PsiUtils.getPrimaryConstructorParameters;
|
||||||
import static org.jetbrains.k2js.translate.utils.TranslationUtils.simpleReturnFunction;
|
import static org.jetbrains.k2js.translate.utils.TranslationUtils.simpleReturnFunction;
|
||||||
|
|
||||||
@@ -220,16 +221,13 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<JsExpression> getSupertypesNameReferences() {
|
private List<JsExpression> getSupertypesNameReferences() {
|
||||||
Collection<JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
|
List<JetType> supertypes = getSupertypesWithoutFakes(descriptor);
|
||||||
if (supertypes.isEmpty()) {
|
if (supertypes.isEmpty()) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
if (supertypes.size() == 1) {
|
if (supertypes.size() == 1) {
|
||||||
JetType type = supertypes.iterator().next();
|
JetType type = supertypes.get(0);
|
||||||
ClassDescriptor supertypeDescriptor = getClassDescriptorForType(type);
|
ClassDescriptor supertypeDescriptor = getClassDescriptorForType(type);
|
||||||
if (isAny(supertypeDescriptor)) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
return Collections.<JsExpression>singletonList(getClassReference(supertypeDescriptor));
|
return Collections.<JsExpression>singletonList(getClassReference(supertypeDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,9 +242,7 @@ public final class ClassTranslator extends AbstractTranslator {
|
|||||||
for (TypeConstructor typeConstructor : sortedAllSuperTypes) {
|
for (TypeConstructor typeConstructor : sortedAllSuperTypes) {
|
||||||
if (supertypeConstructors.contains(typeConstructor)) {
|
if (supertypeConstructors.contains(typeConstructor)) {
|
||||||
ClassDescriptor supertypeDescriptor = getClassDescriptorForTypeConstructor(typeConstructor);
|
ClassDescriptor supertypeDescriptor = getClassDescriptorForTypeConstructor(typeConstructor);
|
||||||
if (!isAny(supertypeDescriptor)) {
|
supertypesRefs.add(getClassReference(supertypeDescriptor));
|
||||||
supertypesRefs.add(getClassReference(supertypeDescriptor));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return supertypesRefs;
|
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.BindingUtils;
|
||||||
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
import org.jetbrains.k2js.translate.utils.TranslationUtils;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.k2js.translate.initializer.InitializerUtils.createClassObjectInitializer;
|
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.getClassDescriptor;
|
||||||
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptor;
|
||||||
|
import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getSupertypesWithoutFakes;
|
||||||
|
|
||||||
public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
||||||
@KotlinSignature("val result: MutableList<JsPropertyInitializer>")
|
@KotlinSignature("val result: MutableList<JsPropertyInitializer>")
|
||||||
@@ -75,12 +75,12 @@ public class DeclarationBodyVisitor extends TranslatorVisitor<Void> {
|
|||||||
public Void visitEnumEntry(@NotNull JetEnumEntry enumEntry, TranslationContext data) {
|
public Void visitEnumEntry(@NotNull JetEnumEntry enumEntry, TranslationContext data) {
|
||||||
JsExpression jsEnumEntryCreation;
|
JsExpression jsEnumEntryCreation;
|
||||||
ClassDescriptor descriptor = getClassDescriptor(data.bindingContext(), enumEntry);
|
ClassDescriptor descriptor = getClassDescriptor(data.bindingContext(), enumEntry);
|
||||||
Collection<JetType> supertypes = descriptor.getTypeConstructor().getSupertypes();
|
List<JetType> supertypes = getSupertypesWithoutFakes(descriptor);
|
||||||
if (enumEntry.getBody() != null || supertypes.size() > 1) {
|
if (enumEntry.getBody() != null || supertypes.size() > 1) {
|
||||||
jsEnumEntryCreation = ClassTranslator.generateClassCreation(enumEntry, descriptor, data);
|
jsEnumEntryCreation = ClassTranslator.generateClassCreation(enumEntry, descriptor, data);
|
||||||
} else {
|
} else {
|
||||||
assert supertypes.size() == 1 : "Simple Enum entry must have one supertype";
|
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));
|
enumEntryList.add(new JsPropertyInitializer(data.getNameForDescriptor(descriptor).makeRef(), jsEnumEntryCreation));
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.k2js.translate.utils;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
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.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
import org.jetbrains.k2js.translate.context.TranslationContext;
|
import org.jetbrains.k2js.translate.context.TranslationContext;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getSuperclassDescriptors;
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
|
||||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject;
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFQName;
|
||||||
|
|
||||||
public final class JsDescriptorUtils {
|
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() {
|
private JsDescriptorUtils() {
|
||||||
}
|
}
|
||||||
@@ -67,6 +75,18 @@ public final class JsDescriptorUtils {
|
|||||||
return findAncestorClass(getSuperclassDescriptors(classDescriptor));
|
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
|
@NotNull
|
||||||
public static DeclarationDescriptor getContainingDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
public static DeclarationDescriptor getContainingDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||||
DeclarationDescriptor containing = descriptor.getContainingDeclaration();
|
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