From 133b84160ed32b288cd8a77bf7144d7024eae7db Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 9 Feb 2016 14:57:07 +0300 Subject: [PATCH] [KT-4124] Fix case of super@labeled recever. Add names to metadata of inner classes. --- .../callTranslator/FunctionCallCases.kt | 3 +- .../translate/context/TranslationContext.java | 25 +++++++++++++-- js/js.translator/testData/kotlin_lib_ecma5.js | 32 +++++++++---------- 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt index f05e8374fe9..c3d8d1a42b2 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/FunctionCallCases.kt @@ -32,7 +32,6 @@ import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils import org.jetbrains.kotlin.js.translate.utils.PsiUtils import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver @@ -233,7 +232,7 @@ object ConstructorCallCase : FunctionCallCase() { val expr = receiver.expression when (expr) { is KtSuperExpression -> { - val superDescriptor = context.bindingContext().get(BindingContext.REFERENCE_TARGET, expr.instanceReference) + val superDescriptor = context.getSuperTarget(expr); val jsReceiver = context.getDispatchReceiver(JsDescriptorUtils.getReceiverParameterForDeclaration(superDescriptor)) (sequenceOf(jsReceiver) + argumentsInfo.translateArguments).toList() } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java index a106c5d9ec1..dc48d86740b 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/TranslationContext.java @@ -27,6 +27,8 @@ import org.jetbrains.kotlin.js.translate.intrinsic.Intrinsics; import org.jetbrains.kotlin.js.translate.utils.TranslationUtils; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtExpression; +import org.jetbrains.kotlin.psi.KtSuperExpression; +import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt; import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.DescriptorUtils; @@ -36,6 +38,7 @@ import java.util.Map; import static org.jetbrains.kotlin.js.translate.context.UsageTrackerKt.getNameForCapturedDescriptor; import static org.jetbrains.kotlin.js.translate.utils.BindingUtils.getDescriptorForElement; +import static org.jetbrains.kotlin.resolve.BindingContext.*; /** * All the info about the state of the translation process. @@ -349,13 +352,16 @@ public class TranslationContext { return alias; } } - if (DescriptorUtils.isSubclass(classDescriptor, cls) || parent == null) { + if (classDescriptor == cls + || (classDescriptor != null && cls != null && DescriptorUtils.isSubclass(classDescriptor, cls)) + || parent == null) { return JsLiteral.THIS; } ClassDescriptor parentDescriptor = parent.classDescriptor; if (classDescriptor != parentDescriptor) { return new JsNameRef("$outer", parent.getDispatchReceiverPath(cls)); - } else { + } + else { return parent.getDispatchReceiverPath(cls); } } @@ -386,7 +392,8 @@ public class TranslationContext { return null; } - private static ClassDescriptor getNearestClass(DeclarationDescriptor declaration) { + @Nullable + private static ClassDescriptor getNearestClass(@Nullable DeclarationDescriptor declaration) { while (declaration != null) { if (declaration instanceof ClassDescriptor) { if (!DescriptorUtils.isAnonymousObject(declaration) @@ -398,4 +405,16 @@ public class TranslationContext { } return null; } + + @NotNull + public DeclarationDescriptor getSuperTarget(KtSuperExpression expression) { + PsiElement labelPsi = bindingContext().get(LABEL_TARGET, expression.getTargetLabel()); + ClassDescriptor labelTarget = (ClassDescriptor) bindingContext().get(DECLARATION_TO_DESCRIPTOR, labelPsi); + if (labelTarget != null) { + return labelTarget; + } + DeclarationDescriptor descriptor = bindingContext().get(REFERENCE_TARGET, expression.getInstanceReference()); + assert descriptor != null : "Missing declaration descriptor: " + PsiUtilsKt.getTextWithLocation(expression); + return descriptor; + } } diff --git a/js/js.translator/testData/kotlin_lib_ecma5.js b/js/js.translator/testData/kotlin_lib_ecma5.js index ce75f44f051..47d10092121 100644 --- a/js/js.translator/testData/kotlin_lib_ecma5.js +++ b/js/js.translator/testData/kotlin_lib_ecma5.js @@ -177,14 +177,7 @@ var Kotlin = {}; Object.defineProperties(prototypeObj, metadata.properties); copyProperties(prototypeObj, metadata.functions); prototypeObj.constructor = constructor; - for (var innerType in metadata.types) { - if (metadata.types.hasOwnProperty(innerType)) { - Object.defineProperty(constructor, innerType, { - get: metadata.types[innerType], - configurable: true - }); - } - } + Kotlin.defineInnerTypes(constructor, metadata.types); if (metadata.baseClass != null) { constructor.baseInitializer = metadata.baseClass; @@ -196,6 +189,19 @@ var Kotlin = {}; return constructor; }; + Kotlin.defineInnerTypes = function(constructor, types) { + for (var innerTypeName in types) { + if (types.hasOwnProperty(innerTypeName)) { + var innerType = types[innerTypeName]; + innerType.className = innerTypeName; + Object.defineProperty(constructor, innerTypeName, { + get: innerType, + configurable: true + }); + } + } + }; + Kotlin.createObjectNow = function (bases, constructor, functions) { var noNameClass = Kotlin.createClassNow(bases, constructor, functions); var obj = new noNameClass(); @@ -215,15 +221,7 @@ var Kotlin = {}; copyProperties(obj.prototype, obj.$metadata$.functions); Object.defineProperty(obj, "object", {get: class_object, configurable: true}); - for (var innerType in obj.$metadata$.types) { - if (obj.$metadata$.types.hasOwnProperty(innerType)) { - Object.defineProperty(constructor, innerType, { - get: obj.$metadata$.types[innerType], - configurable: true - }); - } - } - + Kotlin.defineInnerTypes(constructor, obj.$metadata$.types); return obj; };