diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt index 8145f73c750..72c666a02da 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt @@ -126,7 +126,17 @@ class NameSuggestion { // the class's parent scope. // val parts = mutableListOf() + + // For some strange reason we get FAKE_OVERRIDE for final functions called via subtype's receiver var current: DeclarationDescriptor = descriptor + if (current is CallableMemberDescriptor && current.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + val overridden = getOverridden(current) as CallableMemberDescriptor + if (!overridden.isOverridableOrOverrides) { + current = overridden + } + } + val fixedDescriptor = current + do { parts += getSuggestedName(current) var last = current @@ -146,8 +156,8 @@ class NameSuggestion { parts.reverse() val unmangledName = parts.joinToString("$") - val (id, stable) = mangleNameIfNecessary(unmangledName, descriptor) - return SuggestedName(listOf(id), stable, descriptor, current) + val (id, stable) = mangleNameIfNecessary(unmangledName, fixedDescriptor) + return SuggestedName(listOf(id), stable, fixedDescriptor, current) } // For regular names suggest its string representation @@ -187,6 +197,10 @@ class NameSuggestion { return mangleRegularNameIfNecessary(baseName, overriddenDescriptor) } + private fun getOverridden(descriptor: CallableDescriptor): CallableDescriptor { + return generateSequence(descriptor) { it.overriddenDescriptors.firstOrNull()?.original }.last() + } + private fun mangleRegularNameIfNecessary(baseName: String, descriptor: DeclarationDescriptor): NameAndStability { if (descriptor is ClassOrPackageFragmentDescriptor) { return NameAndStability(baseName, !DescriptorUtils.isDescriptorWithLocalVisibility(descriptor)) @@ -213,6 +227,8 @@ class NameSuggestion { // Make all public declarations stable if (descriptor.visibility == Visibilities.PUBLIC) return mangledAndStable() + if (descriptor is CallableMemberDescriptor && descriptor.isOverridableOrOverrides) return mangledAndStable() + // Make all protected declarations of non-final public classes stable if (descriptor.visibility == Visibilities.PROTECTED && !containingDeclaration.isFinalClass && diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index c9c5d78c9dc..4f35224d86b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -2439,6 +2439,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("internalFunctionFromSuperclass.kt") + public void testInternalFunctionFromSuperclass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/invoke/internalFunctionFromSuperclass.kt"); + doTest(fileName); + } + @TestMetadata("invokeInExtensionFunctionLiteral.kt") public void testInvokeInExtensionFunctionLiteral() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/invoke/invokeInExtensionFunctionLiteral.kt"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java index 67cb3550be9..3581dedba56 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/StaticContext.java @@ -298,7 +298,6 @@ public final class StaticContext { List names = new ArrayList(); if (suggested.getStable()) { - for (String namePart : suggested.getNames()) { names.add(scope.declareName(namePart)); } diff --git a/js/js.translator/testData/box/expression/invoke/internalFunctionFromSuperclass.kt b/js/js.translator/testData/box/expression/invoke/internalFunctionFromSuperclass.kt new file mode 100644 index 00000000000..1f2bc4b0d19 --- /dev/null +++ b/js/js.translator/testData/box/expression/invoke/internalFunctionFromSuperclass.kt @@ -0,0 +1,9 @@ +abstract class A { + final internal fun foo() = "OK" +} + +class B : A() { + fun bar() = foo() +} + +fun box() = B().bar() \ No newline at end of file