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 36ccebbc444..90007e9cf87 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 @@ -62,4 +62,8 @@ public final class ExtensionFunctionTest extends SingleFileTranslationTest { public void testGenericExtension() throws Exception { checkFooBoxIsOk("generic.kt"); } + + public void testExtensionFunctionCalledFromExtensionFunction() throws Exception { + checkFooBoxIsTrue("extensionFunctionCalledFromExtensionFunction.kt"); + } } diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java index 745dacc163d..08e9b3be226 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java @@ -57,4 +57,8 @@ public final class NativeInteropTest extends SingleFileTranslationTest { public void testUndefined() throws Exception { checkFooBoxIsTrue("undefined.kt"); } + + public void testKt1519() throws Exception { + checkFooBoxIsTrue("KT-1519.kt"); + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java index 6ccfa6b0890..de99c283273 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java @@ -44,6 +44,7 @@ import static org.jetbrains.k2js.translate.utils.TranslationUtils.getThisObject; * @author Pavel Talanov */ //TODO: write tests on calling backing fields as functions +//TODO: refactor call parameters to be used across the class public final class CallTranslator extends AbstractTranslator { private static class CallParameters { @@ -95,15 +96,15 @@ public final class CallTranslator extends AbstractTranslator { @NotNull /*package*/ JsExpression translate() { - //NOTE: treat native extension function calls as usual calls if (isIntrinsic()) { return intrinsicInvocation(); } if (isConstructor()) { return constructorCall(); } - if (isNative()) { - return methodCall(); + //NOTE: treat native extension function calls as usual calls + if (isNativeExtensionFunctionCall()) { + return nativeExtensionCall(); } if (isExtensionFunctionLiteral()) { return extensionFunctionLiteralCall(); @@ -114,6 +115,12 @@ public final class CallTranslator extends AbstractTranslator { return methodCall(); } + @NotNull + private JsExpression nativeExtensionCall() { + receiver = getExtensionFunctionCallReceiver(); + return methodCall(); + } + private boolean isIntrinsic() { return context().intrinsics().isIntrinsic(descriptor); } @@ -144,8 +151,8 @@ public final class CallTranslator extends AbstractTranslator { return ReferenceTranslator.translateAsFQReference(descriptor, context()); } - private boolean isNative() { - return AnnotationsUtils.isNativeObject(descriptor); + private boolean isNativeExtensionFunctionCall() { + return AnnotationsUtils.isNativeObject(descriptor) && isExtensionFunction(); } private boolean isExtensionFunctionLiteral() { @@ -251,6 +258,7 @@ public final class CallTranslator extends AbstractTranslator { @NotNull private CallParameters callParameters() { + // TODO: this check corresponds to expression as function, make it clearer if (callee != null) { return new CallParameters(null, callee); } diff --git a/js/js.translator/testFiles/extensionFunction/cases/extensionFunctionCalledFromExtensionFunction.kt b/js/js.translator/testFiles/extensionFunction/cases/extensionFunctionCalledFromExtensionFunction.kt new file mode 100644 index 00000000000..028df1d7d1c --- /dev/null +++ b/js/js.translator/testFiles/extensionFunction/cases/extensionFunctionCalledFromExtensionFunction.kt @@ -0,0 +1,12 @@ +package foo + +class A() { + +} + +fun A.one() = 1 +fun A.two() = one() + one() + +fun box() : Boolean { + return (A().two() == 2) +} \ No newline at end of file diff --git a/js/js.translator/testFiles/native/cases/KT-1519.kt b/js/js.translator/testFiles/native/cases/KT-1519.kt new file mode 100644 index 00000000000..212e021eb4d --- /dev/null +++ b/js/js.translator/testFiles/native/cases/KT-1519.kt @@ -0,0 +1,19 @@ +package foo + +native +class Wow() { + val x : Int = js.noImpl + val y : Int = js.noImpl +} + +native +fun Wow.sum() : Int = js.noImpl + +fun Wow.dblSum() : Int { + return 2 * sum() +} + + +fun box() : Boolean { + return (Wow().dblSum() == 6) +} \ No newline at end of file diff --git a/js/js.translator/testFiles/native/native/KT-1519.js b/js/js.translator/testFiles/native/native/KT-1519.js new file mode 100644 index 00000000000..cf3b5a1e60a --- /dev/null +++ b/js/js.translator/testFiles/native/native/KT-1519.js @@ -0,0 +1,24 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function Wow() { + this.x = 1; + this.y = 2; +} + +Wow.prototype.sum = function() { + return this.x + this.y; +}; \ No newline at end of file