From c705fafc952479a31857f5a26ae06dddcc88d207 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Thu, 11 Feb 2016 20:04:19 +0300 Subject: [PATCH] [KT-4124] Add support for super@Outer.functionName() case --- .../testData/codegen/box/super/kt4173_3.kt | 3 ++ .../js/test/semantics/SuperTestGenerated.java | 12 +++---- .../js/translate/callTranslator/CallInfo.kt | 30 +++++++++++++++++ .../callTranslator/FunctionCallCases.kt | 32 ++++--------------- ...ialbeCallCases.kt => VariableCallCases.kt} | 25 +++------------ .../translate/context/TranslationContext.java | 7 ++-- js/js.translator/testData/kotlin_lib_ecma5.js | 3 +- 7 files changed, 56 insertions(+), 56 deletions(-) rename js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/{VarialbeCallCases.kt => VariableCallCases.kt} (83%) diff --git a/compiler/testData/codegen/box/super/kt4173_3.kt b/compiler/testData/codegen/box/super/kt4173_3.kt index 8c23cf83f28..08f3183fe91 100644 --- a/compiler/testData/codegen/box/super/kt4173_3.kt +++ b/compiler/testData/codegen/box/super/kt4173_3.kt @@ -1,3 +1,6 @@ +// Local classes are still unsupported +// TARGET_BACKEND: JVM + open class C(s: Int) { fun test() { diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/SuperTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/SuperTestGenerated.java index 31ad7c5a427..64a076803b9 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/SuperTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/SuperTestGenerated.java @@ -31,6 +31,12 @@ import java.util.regex.Pattern; @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public class SuperTestGenerated extends AbstractSuperTest { + @TestMetadata("kt4173_3.kt") + public void ignoredKt4173_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt4173_3.kt"); + doTest(fileName); + } + public void testAllFilesPresentInSuper() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/super"), Pattern.compile("^(.+)\\.kt$"), true); } @@ -125,12 +131,6 @@ public class SuperTestGenerated extends AbstractSuperTest { doTest(fileName); } - @TestMetadata("kt4173_3.kt") - public void testKt4173_3() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt4173_3.kt"); - doTest(fileName); - } - @TestMetadata("kt4982.kt") public void testKt4982() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/super/kt4982.kt"); 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 7be936ccba8..f9b443c0b7c 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 @@ -31,6 +31,11 @@ import org.jetbrains.kotlin.js.translate.utils.TranslationUtils import com.google.dart.compiler.backend.js.ast.JsLiteral import com.google.dart.compiler.backend.js.ast.JsConditional import com.google.dart.compiler.backend.js.ast.JsBlock +import org.jetbrains.kotlin.js.translate.general.Translation +import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils +import org.jetbrains.kotlin.psi.KtSuperExpression +import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver +import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver interface CallInfo { val context: TranslationContext @@ -55,6 +60,31 @@ class VariableAccessInfo(callInfo: CallInfo, val value: JsExpression? = null) : class FunctionCallInfo(callInfo: CallInfo, val argumentsInfo: CallArgumentTranslator.ArgumentsInfo) : AbstractCallInfo(), CallInfo by callInfo +val CallInfo.superCallReceiver : JsExpression? + get() { + val receiver = this.resolvedCall.dispatchReceiver + return when (receiver) { + is ExpressionReceiver -> { + val expr = receiver.expression + when (expr) { + is KtSuperExpression -> { + val superDescriptor = context.getSuperTarget(expr); + context.getDispatchReceiver(JsDescriptorUtils.getReceiverParameterForDeclaration(superDescriptor)) + } + else -> { + Translation.translateAsExpression(receiver.expression, context) + } + } + } + is ThisClassReceiver -> { + JsLiteral.THIS + } + else -> { + null + } + } + } + /** * no receivers - extensionOrDispatchReceiver = null, extensionReceiver = null * this - extensionOrDispatchReceiver = this, extensionReceiver = null 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 c3d8d1a42b2..0127b6ff660 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 @@ -23,21 +23,17 @@ import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.js.PredefinedAnnotation import org.jetbrains.kotlin.js.translate.context.Namer import org.jetbrains.kotlin.js.translate.context.TranslationContext -import org.jetbrains.kotlin.js.translate.general.Translation import org.jetbrains.kotlin.js.translate.operation.OperatorTable import org.jetbrains.kotlin.js.translate.reference.CallArgumentTranslator import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils import org.jetbrains.kotlin.js.translate.utils.JsAstUtils -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.calls.tasks.isDynamic import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns -import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver -import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver import org.jetbrains.kotlin.util.OperatorNameConventions -import java.util.ArrayList +import java.util.* fun CallArgumentTranslator.ArgumentsInfo.argsWithReceiver(receiver: JsExpression): List { val allArguments = ArrayList(1 + reifiedArguments.size + valueArguments.size) @@ -226,26 +222,10 @@ object ConstructorCallCase : FunctionCallCase() { val functionRef = context.aliasOrValue(callableDescriptor) { fqName } val constructorDescriptor = callableDescriptor as ConstructorDescriptor - val receiver = this.resolvedCall.dispatchReceiver + val receiver = this.superCallReceiver var allArguments = when (receiver) { - is ExpressionReceiver -> { - val expr = receiver.expression - when (expr) { - is KtSuperExpression -> { - val superDescriptor = context.getSuperTarget(expr); - val jsReceiver = context.getDispatchReceiver(JsDescriptorUtils.getReceiverParameterForDeclaration(superDescriptor)) - (sequenceOf(jsReceiver) + argumentsInfo.translateArguments).toList() - } - else -> { - val jsReceiver = Translation.translateAsExpression(receiver.expression, context) - (sequenceOf(jsReceiver) + argumentsInfo.translateArguments).toList() - } - } - } - is ThisClassReceiver -> { - (sequenceOf(JsLiteral.THIS) + argumentsInfo.translateArguments).toList() - } - else -> argumentsInfo.translateArguments + null -> argumentsInfo.translateArguments + else -> (sequenceOf(receiver) + argumentsInfo.translateArguments).toList() } if (constructorDescriptor.isPrimary || AnnotationsUtils.isNativeObject(constructorDescriptor)) { @@ -266,7 +246,9 @@ object SuperCallCase : FunctionCallCase() { // TODO: spread operator val prototypeClass = JsNameRef(Namer.getPrototypeName(), dispatchReceiver!!) val functionRef = Namer.getFunctionCallRef(JsNameRef(functionName, prototypeClass)) - return JsInvocation(functionRef, argumentsInfo.argsWithReceiver(JsLiteral.THIS)) + val superReceiver = this.superCallReceiver + val receiver = if (superReceiver != null) superReceiver else JsLiteral.THIS; + return JsInvocation(functionRef, argumentsInfo.argsWithReceiver(receiver)) } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VarialbeCallCases.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VariableCallCases.kt similarity index 83% rename from js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VarialbeCallCases.kt rename to js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VariableCallCases.kt index eb5f5dc03d2..1f67bde0035 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VarialbeCallCases.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/callTranslator/VariableCallCases.kt @@ -25,10 +25,6 @@ import java.util.Collections import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure import org.jetbrains.kotlin.js.translate.context.Namer.getCapturedVarAccessor -import org.jetbrains.kotlin.js.translate.general.Translation -import org.jetbrains.kotlin.js.translate.utils.JsDescriptorUtils -import org.jetbrains.kotlin.psi.KtSuperExpression -import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver object NativeVariableAccessCase : VariableAccessCase() { @@ -114,23 +110,10 @@ object DelegatePropertyAccessIntrinsic : DelegateIntrinsic { object SuperPropertyAccessCase : VariableAccessCase() { override fun VariableAccessInfo.dispatchReceiver(): JsExpression { val variableName = context.program().getStringLiteral(this.variableName.ident) - val receiver = this.resolvedCall.dispatchReceiver - var propertyOwner = when (receiver) { - is ExpressionReceiver -> { - val expr = receiver.expression - when (expr) { - is KtSuperExpression -> { - val superDescriptor = context.getSuperTarget(expr); - context.getDispatchReceiver(JsDescriptorUtils.getReceiverParameterForDeclaration(superDescriptor)) - } - else -> { - Translation.translateAsExpression(receiver.expression, context) - } - } - } - else -> { - JsLiteral.THIS - } + val jsReceiver = this.superCallReceiver + var propertyOwner = when (jsReceiver) { + null -> JsLiteral.THIS + else -> jsReceiver } return if (isGetAccess()) JsInvocation(context.namer().callGetProperty, propertyOwner, dispatchReceiver!!, variableName) 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 77e45e57517..b42c5618095 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 @@ -379,9 +379,10 @@ public class TranslationContext { return alias; } } - if (classDescriptor == cls - || (classDescriptor != null && cls != null && 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; diff --git a/js/js.translator/testData/kotlin_lib_ecma5.js b/js/js.translator/testData/kotlin_lib_ecma5.js index 411ba67a477..e0b096a56e4 100644 --- a/js/js.translator/testData/kotlin_lib_ecma5.js +++ b/js/js.translator/testData/kotlin_lib_ecma5.js @@ -125,7 +125,8 @@ var Kotlin = {}; property = staticProperties[p]; if (typeof property === "function" && typeof property.type !== "undefined" && property.type === Kotlin.TYPE.INIT_FUN) { metadata.types[p] = property; - } else { + } + else { metadata.staticMembers[p] = property; } }