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 de136f8f1e6..9c8435c2308 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 @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.isEnumValueOfMethod import java.util.* @@ -184,12 +185,17 @@ class NameSuggestion { if (nativeName != null) return Pair(nativeName, true) val stable = shouldBeStable(descriptor) - val finalName = if (overriddenDescriptor is CallableDescriptor && stable) { - getStableMangledName(baseName, getArgumentTypesAsString(overriddenDescriptor)) - } - else { - baseName + val finalName = when { + overriddenDescriptor is CallableDescriptor && stable -> { + getStableMangledName(baseName, getArgumentTypesAsString(overriddenDescriptor)) + } + shouldMangleUnstable(overriddenDescriptor) -> { + val ownerName = descriptor.containingDeclaration!!.fqNameUnsafe.asString() + getStableMangledName(baseName, ownerName + ":" + getArgumentTypesAsString(overriddenDescriptor as CallableDescriptor)) + } + else -> baseName } + return Pair(finalName, stable) } @@ -206,6 +212,20 @@ class NameSuggestion { return argTypes.toString() } + // Sometimes private members of a class can clash with public members of subclasses, therefore we must + // mangle them + private fun shouldMangleUnstable(descriptor: DeclarationDescriptor): Boolean { + if (descriptor is ClassDescriptor) return false + if (DescriptorUtils.isDescriptorWithLocalVisibility(descriptor)) return false + + val containingClass = DescriptorUtils.getContainingClass(descriptor) + if (containingClass != null && descriptor is CallableMemberDescriptor && !descriptor.isOverridable) { + return containingClass.visibility.isPublicAPI + } + + return false + } + fun getStableMangledName(suggestedName: String, forCalculateId: String): String { val suffix = if (forCalculateId.isEmpty()) "" else "_${mangledId(forCalculateId)}\$" return suggestedName + suffix