JS: fix generation of names for local declarations

Local declarations obtain names prefixed with outer function's name.
Only simple name (i.e. without mangling) of outer function used
in this case. This raises a problem in case of inline functions
with object literals. Currently, they are not copied, but exported
from module. Consider two inline functions foo with different
signatures, both declare object literals. In this case both literals
are exported as foo$f, so only one will be accessible from outside.
This commit is contained in:
Alexey Andreev
2017-04-21 15:12:24 +03:00
parent 88cf37951b
commit feb968e66d
3 changed files with 45 additions and 8 deletions
@@ -170,15 +170,21 @@ class NameSuggestion {
}
val fixedDescriptor = current
do {
parts += getSuggestedName(current)
val last = current
parts += if (fixedDescriptor is ConstructorDescriptor) {
current = current.containingDeclaration!!
if (last is ConstructorDescriptor && !last.isPrimary) {
parts[parts.lastIndex] = getSuggestedName(current) + "_init"
current = current.containingDeclaration!!
}
} while (current is FunctionDescriptor)
getSuggestedName(current) + "_init"
}
else {
getSuggestedName(fixedDescriptor)
}
if (current.containingDeclaration is FunctionDescriptor && current !is TypeParameterDescriptor) {
val outerFunctionName = suggest(current.containingDeclaration as FunctionDescriptor)!!
parts += outerFunctionName.names.single()
current = outerFunctionName.scope
}
else {
current = current.containingDeclaration!!
}
// Getters and setters have generation strategy similar to common declarations, except for they are declared as
// members of classes/packages, not corresponding properties.
@@ -4421,6 +4421,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("js/js.translator/testData/box/inlineMultiFile"), Pattern.compile("^([^_](.+))\\.kt$"), TargetBackend.JS, true);
}
@TestMetadata("anonymousObjectInSimilarFunctions.kt")
public void testAnonymousObjectInSimilarFunctions() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/inlineMultiFile/anonymousObjectInSimilarFunctions.kt");
doTest(fileName);
}
@TestMetadata("anonymousObjectOnCallSite.kt")
public void testAnonymousObjectOnCallSite() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/inlineMultiFile/anonymousObjectOnCallSite.kt");
@@ -0,0 +1,25 @@
// FILE: a.kt
inline fun foo(x: String): I = object : I {
override fun get(): String = "foo_String($x)"
}
// FILE: b.kt
inline fun foo(x: Int): I = object : I {
override fun get(): String = "foo_Int($x)"
}
// FILE: main.kt
interface I {
fun get(): String
}
fun box(): String {
val a = foo("1").get()
if (a != "foo_String(1)") return "fail1: $a"
val b = foo(2).get()
if (b != "foo_Int(2)") return "fail2: $b"
return "OK"
}