diff --git a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/metadata/metadataProperties.kt b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/metadata/metadataProperties.kt index d72731cd804..cadb11e7f58 100644 --- a/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/metadata/metadataProperties.kt +++ b/js/js.dart-ast/src/com/google/dart/compiler/backend/js/ast/metadata/metadataProperties.kt @@ -62,8 +62,7 @@ enum class TypeCheck { INSTANCEOF, OR_NULL, IS_ANY, - AND_PREDICATE, - SAME_AS + AND_PREDICATE } enum class SideEffectKind { diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt index 490b80a9471..1a92ed4996b 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/CallInfo.kt @@ -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 = resolvedCall diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java index 6d56a2efc65..6bbb96a5435 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/Namer.java @@ -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); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java index 1fa7a925f62..128ef0f5944 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java @@ -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 orderedClasses = DFS.topologicalOrder(classes, new DFS.Neighbors() { + @NotNull + @Override + public Iterable getNeighbors(ClassDescriptor current) { + return DescriptorUtils.getSuperclassDescriptors(current); } + }); + Collections.reverse(orderedClasses); + for (ClassDescriptor classDescriptor : orderedClasses) { + ClassTranslator.addInterfaceDefaultMembers(classDescriptor, this); } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt index 74ee3fffd29..8bf6b9b268f 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/ClassTranslator.kt @@ -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) } } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt index c7b2ec9dd89..d1032f4d200 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.kt @@ -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++ } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java index 21c3a47ccab..08ebdcc7ef0 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/PatternTranslator.java @@ -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 diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/expandIsCalls.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/expandIsCalls.kt index 47f5f75057e..3f75150aca2 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/expandIsCalls.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/expandIsCalls.kt @@ -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 diff --git a/js/js.translator/testData/box/reflection/jsClassName.kt b/js/js.translator/testData/box/reflection/jsClassName.kt index c075df98aec..7c9655ba64e 100644 --- a/js/js.translator/testData/box/reflection/jsClassName.kt +++ b/js/js.translator/testData/box/reflection/jsClassName.kt @@ -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().name) assertEquals("I", jsClass().name) assertEquals("E", jsClass().name) - assertEquals("Q", jsClass().name) + assertEquals("R", jsClass().name) } fun box(): String {