JS: fix some minor issues in new flat translator

This commit is contained in:
Alexey Andreev
2016-10-19 15:52:09 +03:00
parent 06476402a2
commit bb57eaef96
9 changed files with 39 additions and 23 deletions
@@ -62,8 +62,7 @@ enum class TypeCheck {
INSTANCEOF,
OR_NULL,
IS_ANY,
AND_PREDICATE,
SAME_AS
AND_PREDICATE
}
enum class SideEffectKind {
@@ -25,8 +25,10 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator
import org.jetbrains.kotlin.js.translate.reference.ReferenceTranslator
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getReceiverParameterForReceiver
import org.jetbrains.kotlin.js.translate.utils.TranslationUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
@@ -144,6 +146,14 @@ private fun TranslationContext.createCallInfo(
}
}
}
if (dispatchReceiver == null) {
val container = resolvedCall.resultingDescriptor.containingDeclaration
if (DescriptorUtils.isObject(container)) {
dispatchReceiver = ReferenceTranslator.translateAsValueReference(container, this)
}
}
return object : AbstractCallInfo(), CallInfo {
override val context: TranslationContext = this@createCallInfo
override val resolvedCall: ResolvedCall<out CallableDescriptor> = resolvedCall
@@ -320,11 +320,6 @@ public final class Namer {
return invokeFunctionAndSetTypeCheckMetadata("isInstanceOf", type, TypeCheck.INSTANCEOF);
}
@NotNull
public JsExpression isInstanceOfObject(@NotNull JsExpression type) {
return invokeFunctionAndSetTypeCheckMetadata("isInstanceOf", type, TypeCheck.SAME_AS);
}
@NotNull
public JsExpression orNull(@NotNull JsExpression callable) {
return invokeFunctionAndSetTypeCheckMetadata("orNull", callable, TypeCheck.OR_NULL);
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.tasks.DynamicCallsKt;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.utils.DFS;
import java.util.*;
@@ -752,10 +753,16 @@ public final class StaticContext {
}
private void addInterfaceDefaultMethods() {
for (ClassDescriptor classDescriptor : classes) {
if (classDescriptor.getKind() != ClassKind.INTERFACE) {
ClassTranslator.addInterfaceDefaultMembers(classDescriptor, this);
List<ClassDescriptor> orderedClasses = DFS.topologicalOrder(classes, new DFS.Neighbors<ClassDescriptor>() {
@NotNull
@Override
public Iterable<? extends ClassDescriptor> getNeighbors(ClassDescriptor current) {
return DescriptorUtils.getSuperclassDescriptors(current);
}
});
Collections.reverse(orderedClasses);
for (ClassDescriptor classDescriptor : orderedClasses) {
ClassTranslator.addInterfaceDefaultMembers(classDescriptor, this);
}
}
@@ -180,6 +180,12 @@ class ClassTranslator private constructor(
metadataLiteral.propertyInitializers += JsPropertyInitializer(JsNameRef("type"), typeRef)
metadataLiteral.propertyInitializers += JsPropertyInitializer(JsNameRef("classIndex"), typeIndex)
val simpleName = descriptor.name
if (!simpleName.isSpecial) {
val simpleNameProp = JsPropertyInitializer(JsNameRef("simpleName"), program().getStringLiteral(simpleName.identifier))
metadataLiteral.propertyInitializers += simpleNameProp
}
}
private fun generateSecondaryConstructor(classContext: TranslationContext, constructor: KtSecondaryConstructor) {
@@ -506,12 +512,16 @@ class ClassTranslator private constructor(
DescriptorUtils.isInterface(it.containingDeclaration) }
.firstOrNull() ?: continue
if (overriddenFunction.modality == Modality.ABSTRACT) continue
val interfaceDescriptor = overriddenFunction.containingDeclaration as ClassDescriptor
if (interfaceDescriptor.kind != ClassKind.INTERFACE) continue
val directContainer = member.overriddenDescriptors.first().containingDeclaration as ClassDescriptor
when (member) {
is FunctionDescriptor -> addDefaultMethodFromInterface(member, interfaceDescriptor, descriptor, context)
is PropertyDescriptor -> addDefaultPropertyFromInterface(member, interfaceDescriptor, descriptor, context)
is FunctionDescriptor -> addDefaultMethodFromInterface(member, directContainer, descriptor, context)
is PropertyDescriptor -> addDefaultPropertyFromInterface(member, directContainer, descriptor, context)
}
}
}
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.js.translate.utils.BindingUtils.getClassDescriptor
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils.pureFqn
import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils.getSupertypesWithoutFakes
import org.jetbrains.kotlin.psi.*
import java.util.*
class DeclarationBodyVisitor(
private val containingClass: ClassDescriptor,
@@ -78,6 +77,8 @@ class DeclarationBodyVisitor(
enumInstanceFunction.body.statements += JsReturn(enumInstanceName.makeRef())
}
context.export(descriptor)
enumEntryOrdinal++
}
@@ -171,7 +171,7 @@ public final class PatternTranslator extends AbstractTranslator {
ClassDescriptor referencedClass = DescriptorUtils.getClassDescriptorForType(type);
JsExpression typeName = ReferenceTranslator.translateAsTypeReference(referencedClass, context());
return referencedClass.getKind() != ClassKind.OBJECT ? namer().isInstanceOf(typeName) : namer().isInstanceOfObject(typeName);
return namer().isInstanceOf(typeName);
}
@Nullable
@@ -86,12 +86,6 @@ private class TypeCheckRewritingVisitor(private val context: TranslationContext)
if (calleeArguments.size == 1) context.namer().isInstanceOf(argument, calleeArguments[0]) else null
}
TypeCheck.SAME_AS -> {
// `Kotlin.isInstanceOf(calleeArgument)(argument)` -> `argument === calleeArgument`
// when it's known at compile time that `argument` represents an object type
if (calleeArguments.size == 1) JsAstUtils.equality(argument, calleeArguments[0]) else null
}
TypeCheck.OR_NULL -> {
// `Kotlin.orNull(calleeArgument)(argument)` -> `(tmp = argument) == null || calleeArgument(tmp)`
if (calleeArguments.size == 1) getReplacementForOrNull(argument, calleeArguments[0]) else null
+3 -3
View File
@@ -5,10 +5,10 @@ fun testWithInstance() {
assertEquals("B", B().jsClass.name)
assertEquals("O", O.jsClass.name)
assertEquals("E", E.X.jsClass.name)
assertEquals("Y", E.Y.jsClass.name)
assertEquals("E\$Y", E.Y.jsClass.name)
// TODO uncomment after KT-13338 is fixed
// assertEquals("E", E.Z.jsClass.name)
assertEquals("Q", R().jsClass.name)
assertEquals("R", R().jsClass.name)
}
fun testWithClassReference() {
@@ -17,7 +17,7 @@ fun testWithClassReference() {
assertEquals("O", jsClass<O>().name)
assertEquals("I", jsClass<I>().name)
assertEquals("E", jsClass<E>().name)
assertEquals("Q", jsClass<R>().name)
assertEquals("R", jsClass<R>().name)
}
fun box(): String {