KT-2752: fix translation of call to internal function from subclass

This commit is contained in:
Alexey Andreev
2016-10-07 15:31:28 +03:00
parent c814a9d1d2
commit 322f6fe7ac
4 changed files with 33 additions and 3 deletions
@@ -126,7 +126,17 @@ class NameSuggestion {
// the class's parent scope. // the class's parent scope.
// //
val parts = mutableListOf<String>() val parts = mutableListOf<String>()
// For some strange reason we get FAKE_OVERRIDE for final functions called via subtype's receiver
var current: DeclarationDescriptor = descriptor 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 { do {
parts += getSuggestedName(current) parts += getSuggestedName(current)
var last = current var last = current
@@ -146,8 +156,8 @@ class NameSuggestion {
parts.reverse() parts.reverse()
val unmangledName = parts.joinToString("$") val unmangledName = parts.joinToString("$")
val (id, stable) = mangleNameIfNecessary(unmangledName, descriptor) val (id, stable) = mangleNameIfNecessary(unmangledName, fixedDescriptor)
return SuggestedName(listOf(id), stable, descriptor, current) return SuggestedName(listOf(id), stable, fixedDescriptor, current)
} }
// For regular names suggest its string representation // For regular names suggest its string representation
@@ -187,6 +197,10 @@ class NameSuggestion {
return mangleRegularNameIfNecessary(baseName, overriddenDescriptor) 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 { private fun mangleRegularNameIfNecessary(baseName: String, descriptor: DeclarationDescriptor): NameAndStability {
if (descriptor is ClassOrPackageFragmentDescriptor) { if (descriptor is ClassOrPackageFragmentDescriptor) {
return NameAndStability(baseName, !DescriptorUtils.isDescriptorWithLocalVisibility(descriptor)) return NameAndStability(baseName, !DescriptorUtils.isDescriptorWithLocalVisibility(descriptor))
@@ -213,6 +227,8 @@ class NameSuggestion {
// Make all public declarations stable // Make all public declarations stable
if (descriptor.visibility == Visibilities.PUBLIC) return mangledAndStable() 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 // Make all protected declarations of non-final public classes stable
if (descriptor.visibility == Visibilities.PROTECTED && if (descriptor.visibility == Visibilities.PROTECTED &&
!containingDeclaration.isFinalClass && !containingDeclaration.isFinalClass &&
@@ -2439,6 +2439,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
doTest(fileName); 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") @TestMetadata("invokeInExtensionFunctionLiteral.kt")
public void testInvokeInExtensionFunctionLiteral() throws Exception { public void testInvokeInExtensionFunctionLiteral() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/invoke/invokeInExtensionFunctionLiteral.kt"); String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/invoke/invokeInExtensionFunctionLiteral.kt");
@@ -298,7 +298,6 @@ public final class StaticContext {
List<JsName> names = new ArrayList<JsName>(); List<JsName> names = new ArrayList<JsName>();
if (suggested.getStable()) { if (suggested.getStable()) {
for (String namePart : suggested.getNames()) { for (String namePart : suggested.getNames()) {
names.add(scope.declareName(namePart)); names.add(scope.declareName(namePart));
} }
@@ -0,0 +1,9 @@
abstract class A {
final internal fun foo() = "OK"
}
class B : A() {
fun bar() = foo()
}
fun box() = B().bar()