From e0ff877b4729c842afe307e76e6d1183ffab8c43 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Tue, 31 Jul 2012 13:15:12 +0400 Subject: [PATCH] Fix for a bug that caused invalid code generated for calling extension from another extension. --- .../test/semantics/ExtensionFunctionTest.java | 12 ++++++++++++ .../reference/CallParametersResolver.java | 7 +++---- .../k2js/translate/utils/JsDescriptorUtils.java | 17 +++++++++++++++++ .../cases/extensionForSuperclass.kt | 17 +++++++++++++++++ .../cases/implicitReceiverInExtension.kt | 7 +++++++ .../cases/superClassMemberInExtension.kt | 14 ++++++++++++++ 6 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 js/js.translator/testFiles/extensionFunction/cases/extensionForSuperclass.kt create mode 100644 js/js.translator/testFiles/extensionFunction/cases/implicitReceiverInExtension.kt create mode 100644 js/js.translator/testFiles/extensionFunction/cases/superClassMemberInExtension.kt diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionFunctionTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionFunctionTest.java index c5bbaa32be5..194db440c11 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionFunctionTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/ExtensionFunctionTest.java @@ -78,4 +78,16 @@ public final class ExtensionFunctionTest extends SingleFileTranslationTest { public void testExtensionFunctionCalledFromFor() throws Exception { fooBoxTest(); } + + public void testImplicitReceiverInExtension() throws Exception { + fooBoxTest(); + } + + public void testExtensionForSuperclass() throws Exception { + fooBoxTest(); + } + + public void testSuperClassMemberInExtension() throws Exception { + fooBoxTest(); + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParametersResolver.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParametersResolver.java index fff7c0cf180..5dd69d959d5 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParametersResolver.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallParametersResolver.java @@ -28,7 +28,7 @@ import org.jetbrains.jet.lang.resolve.calls.VariableAsFunctionResolvedCall; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.utils.TranslationUtils; -import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getExpectedReceiverDescriptor; +import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getDeclarationDescriptorForExtensionCallReceiver; /** * @author Pavel Talanov @@ -106,8 +106,7 @@ public final class CallParametersResolver { if (qualifier != null) { return qualifier; } - DeclarationDescriptor expectedReceiverDescriptor = getExpectedReceiverDescriptor(resolvedCall.getResultingDescriptor()); - assert expectedReceiverDescriptor != null; - return TranslationUtils.getThisObject(context, expectedReceiverDescriptor); + DeclarationDescriptor receiverDescriptor = getDeclarationDescriptorForExtensionCallReceiver(resolvedCall); + return TranslationUtils.getThisObject(context, receiverDescriptor); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java index 7f8818d5c4a..23ee79eecde 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java @@ -25,6 +25,9 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ClassReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; @@ -231,4 +234,18 @@ public final class JsDescriptorUtils { !isDefaultAccessor(propertyDescriptor.getGetter()) || !isDefaultAccessor(propertyDescriptor.getSetter()); } + + @NotNull + public static DeclarationDescriptor getDeclarationDescriptorForExtensionCallReceiver( + @NotNull ResolvedCall resolvedCall + ) { + ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument(); + if (receiverArgument instanceof ExtensionReceiver) { + return ((ExtensionReceiver) receiverArgument).getDeclarationDescriptor(); + } + if (receiverArgument instanceof ClassReceiver) { + return ((ClassReceiver)receiverArgument).getDeclarationDescriptor(); + } + throw new IllegalStateException("Unexpected receiver of type " + receiverArgument.getClass()); + } } diff --git a/js/js.translator/testFiles/extensionFunction/cases/extensionForSuperclass.kt b/js/js.translator/testFiles/extensionFunction/cases/extensionForSuperclass.kt new file mode 100644 index 00000000000..35204e71d9e --- /dev/null +++ b/js/js.translator/testFiles/extensionFunction/cases/extensionForSuperclass.kt @@ -0,0 +1,17 @@ +package foo + +open class A() { + open fun c() = 2 +} + +class B(): A() { + override fun c() = 3 +} + +fun B.t() = d() + 1 + +fun A.d() = c() + 3 + +fun box() : Boolean { + return A().d() == 5 && B().d() == 6 && B().t() == 7 +} diff --git a/js/js.translator/testFiles/extensionFunction/cases/implicitReceiverInExtension.kt b/js/js.translator/testFiles/extensionFunction/cases/implicitReceiverInExtension.kt new file mode 100644 index 00000000000..b34d5341ac7 --- /dev/null +++ b/js/js.translator/testFiles/extensionFunction/cases/implicitReceiverInExtension.kt @@ -0,0 +1,7 @@ +package foo + +fun T.toPrefixedString(prefix: String = "", suffix: String="") = prefix + toString() + suffix + +fun box() : Boolean { + return ("mama".toPrefixedString(suffix="321", prefix="papa") == "papamama321") +} diff --git a/js/js.translator/testFiles/extensionFunction/cases/superClassMemberInExtension.kt b/js/js.translator/testFiles/extensionFunction/cases/superClassMemberInExtension.kt new file mode 100644 index 00000000000..0901eadadee --- /dev/null +++ b/js/js.translator/testFiles/extensionFunction/cases/superClassMemberInExtension.kt @@ -0,0 +1,14 @@ +package foo + +open class A() { + open fun c() = 2 +} + +class B(): A() { +} + +fun B.d() = c() + 3 + +fun box() : Boolean { + return B().d() == 5 +}