From 92e76d18d98e93936c981fd494d7431e688da3c5 Mon Sep 17 00:00:00 2001 From: develar Date: Fri, 23 Aug 2013 14:47:25 +0400 Subject: [PATCH] JS backend: change name mangling -- right now before indexing we sort functions by Visibility and Modality. (cherry picked from commit 7620a07) --- .../test/semantics/IdentifierClashTest.java | 4 ++ .../k2js/translate/context/StaticContext.java | 42 ++++++++++++++++++- .../identifierClash/cases/overloadedFun.kt | 18 ++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 js/js.translator/testFiles/expression/identifierClash/cases/overloadedFun.kt diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/IdentifierClashTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/IdentifierClashTest.java index 24c4efe7f4b..430c59bb6bc 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/IdentifierClashTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/IdentifierClashTest.java @@ -26,6 +26,10 @@ public final class IdentifierClashTest extends AbstractExpressionTest { fooBoxTest(); } + public void testOverloadedFun() throws Exception { + fooBoxTest(); + } + public void testDummyFunctionToMakeTestWork() { } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java index c9ed94ee6da..7c66fcc04bf 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java @@ -38,6 +38,9 @@ import org.jetbrains.k2js.translate.utils.JsAstUtils; import org.jetbrains.k2js.translate.utils.JsDescriptorUtils; import org.jetbrains.k2js.translate.utils.PredefinedAnnotation; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; import java.util.Map; import static org.jetbrains.k2js.translate.utils.AnnotationsUtils.*; @@ -232,7 +235,44 @@ public final class StaticContext { @Nullable public JsName apply(@NotNull DeclarationDescriptor descriptor) { JsScope scope = getEnclosingScope(descriptor); - return scope.declareFreshName(descriptor.getName().asString()); + DeclarationDescriptor declaration = descriptor.getContainingDeclaration(); + if (!(descriptor instanceof FunctionDescriptor) || !(declaration instanceof ClassDescriptor)) { + return scope.declareFreshName(descriptor.getName().asString()); + } + + Collection functions = + ((ClassDescriptor) declaration).getDefaultType().getMemberScope().getFunctions(descriptor.getName()); + String name = descriptor.getName().asString(); + int counter = -1; + if (functions.size() > 1) { + // see testOverloadedFun + FunctionDescriptor[] sorted = functions.toArray(new FunctionDescriptor[functions.size()]); + Arrays.sort(sorted, new Comparator() { + @Override + public int compare(@NotNull FunctionDescriptor a, @NotNull FunctionDescriptor b) { + Integer result = Visibilities.compare(b.getVisibility(), a.getVisibility()); + if (result == null) { + return 0; + } + else if (result == 0) { + // open fun > not open fun + int aWeight = a.getModality().isOverridable() ? 1 : 0; + int bWeight = b.getModality().isOverridable() ? 1 : 0; + return bWeight - aWeight; + } + + return result; + } + }); + for (FunctionDescriptor function : sorted) { + if (function == descriptor) { + break; + } + counter++; + } + } + + return scope.declareName(counter == -1 ? name : name + '_' + counter); } }; Rule constructorHasTheSameNameAsTheClass = new Rule() { diff --git a/js/js.translator/testFiles/expression/identifierClash/cases/overloadedFun.kt b/js/js.translator/testFiles/expression/identifierClash/cases/overloadedFun.kt new file mode 100644 index 00000000000..06902588beb --- /dev/null +++ b/js/js.translator/testFiles/expression/identifierClash/cases/overloadedFun.kt @@ -0,0 +1,18 @@ +package foo + +abstract class B { + abstract fun foo(param: String): String +} + +class A : B() { + // must be here - before open fun foo(String) + private fun foo(param: Int) = "foo(Int)" + + fun foo() = "foo()" + + override fun foo(param: String) = "foo(String)" +} + +fun box(): Boolean { + return A().foo("OK") == "foo(String)" +} \ No newline at end of file