diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java index a6fee9c6a5c..ba67cdc4c9a 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java @@ -62,27 +62,22 @@ public class FunctionTest extends AbstractExpressionTest { checkFooBoxIsOk(); } - public void testImplicitItParameter() throws Exception { fooBoxTest(); } - public void testDefaultParameters() throws Exception { fooBoxTest(); } - public void testFunctionLiteralAsLastParameter() throws Exception { fooBoxTest(); } - public void testNamedArguments() throws Exception { fooBoxTest(); } - public void testExpressionAsFunction() throws Exception { fooBoxTest(); } @@ -132,6 +127,10 @@ public class FunctionTest extends AbstractExpressionTest { checkFooBoxIsOk(); } + public void testManglingClashWithFunctionsWithoutParameters() throws Exception { + checkFooBoxIsOk(); + } + public void testLocalExtFunction() throws Exception { checkFooBoxIsOk(); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java index 873ab047135..e0007ec82bd 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java @@ -246,9 +246,10 @@ public final class TranslationUtils { String name = AnnotationsUtils.getNameForAnnotatedObjectWithOverrides(functionDescriptor); + // when name == null it's mean that it's not native. if (name == null) { - // when name == null it's mean that it's not native - if (needsStableMangling(functionDescriptor)) return null; + // skip functions without arguments, because we don't use mangling for them + if (needsStableMangling(functionDescriptor) && !functionDescriptor.getValueParameters().isEmpty()) return null; name = declarationDescriptor.getName().asString(); } diff --git a/js/js.translator/testData/expression/function/cases/manglingClashWithFunctionsWithoutParameters.kt b/js/js.translator/testData/expression/function/cases/manglingClashWithFunctionsWithoutParameters.kt new file mode 100644 index 00000000000..39c5bb555cd --- /dev/null +++ b/js/js.translator/testData/expression/function/cases/manglingClashWithFunctionsWithoutParameters.kt @@ -0,0 +1,62 @@ +package foo + +fun foo(i: Int): String = "foo" + i +public fun foo(): Int = 4 +public fun boo(): Int = 23 +fun boo(i: Int): String = "boo" + i + +trait T { + public fun foo(): Int + public fun boo(): Int +} + +public class A : T { + fun foo(i: Int): String = "A.foo" + i + override fun foo(): Int = 42 + override fun boo(): Int = 2 + fun boo(i: Int): String = "A.boo" + i +} + +// Helpers +native +fun String.replace(regexp: RegExp, replacement: String): String = noImpl + +fun String.replaceAll(regexp: String, replacement: String): String = replace(RegExp(regexp, "g"), replacement) + +native +class RegExp(regexp: String, flags: String) + +//Testing + +fun test(testName: String, ff: Any, fb: Any) { + val f = ff.toString() + val b = fb.toString().replaceAll("boo", "foo") + + if (f != b) throw Exception("FAILED on ${testName}:\n f = \"$f\"\n b = \"$b\"") +} + +fun assertEquals(expected: T, actual: T) { + if (expected != actual) throw Exception("expected: $expected, actual: $actual") +} + +fun box(): String { + val a = A() + + test("foo()", { foo() }, { boo() }) + test("foo(Int)", { foo(1) }, { boo(1) }) + + test("a.foo()", { a.foo() }, { a.boo() }) + test("a.foo(Int)", { a.foo(1) }, { a.boo(1) }) + + assertEquals("foo3", foo(3)) + assertEquals(4, foo()) + assertEquals(23, boo()) + assertEquals("boo6", boo(6)) + + assertEquals("A.foo3", a.foo(3)) + assertEquals(42, a.foo()) + assertEquals(2, a.boo()) + assertEquals("A.boo35", a.boo(35)) + + return "OK" +}