JS: test local declaration deduplication with name clash; fix the test
This commit is contained in:
@@ -29,6 +29,8 @@ sealed class InliningScope {
|
||||
|
||||
abstract fun addImport(tag: String, vars: JsVars)
|
||||
|
||||
open fun addLocalDeclarationBinding(inlineFunctionTag: String, name: JsName, index: Int) {}
|
||||
|
||||
open fun preprocess(statement: JsStatement) {}
|
||||
|
||||
abstract fun update()
|
||||
@@ -82,16 +84,26 @@ sealed class InliningScope {
|
||||
}
|
||||
}
|
||||
|
||||
val localDeclarations = mutableListOf<JsName>()
|
||||
|
||||
copiedStatements.asSequence()
|
||||
.flatMap { node -> collectDefinedNamesInAllScopes(node).asSequence() }
|
||||
.filter { name -> !newReplacements.containsKey(name) }
|
||||
.forEach { name ->
|
||||
val alias = JsScope.declareTemporaryName(name.ident)
|
||||
alias.copyMetadataFrom(name)
|
||||
localDeclarations += alias
|
||||
val replacement = JsAstUtils.pureFqn(alias, null)
|
||||
newReplacements[name] = replacement
|
||||
}
|
||||
|
||||
// Add local declarations to the nae bindings in order to correctly rename usages of the same imported local declaraions
|
||||
definition.tag?.let { tag ->
|
||||
localDeclarations.forEachIndexed { index, name ->
|
||||
addLocalDeclarationBinding(tag, name, index)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply renaming and restore the static ref links
|
||||
JsBlock(copiedStatements).let {
|
||||
replaceNames(it, newReplacements)
|
||||
@@ -190,6 +202,10 @@ class ProgramFragmentInliningScope(
|
||||
addNameBinding(name, tag)
|
||||
}
|
||||
|
||||
override fun addLocalDeclarationBinding(inlineFunctionTag: String, name: JsName, index: Int) {
|
||||
addNameBinding(name, "\$local:$inlineFunctionTag:$index")
|
||||
}
|
||||
|
||||
override fun addInlinedDeclaration(tag: String?, declaration: JsStatement) {
|
||||
if (tag != null) {
|
||||
fragment.inlinedLocalDeclarations.computeIfAbsent(tag) { JsGlobalBlock() }.statements.add(declaration)
|
||||
|
||||
@@ -125,6 +125,7 @@ fun collectDefinedNames(scope: JsNode): Set<JsName> {
|
||||
}
|
||||
|
||||
fun collectDefinedNamesInAllScopes(scope: JsNode): Set<JsName> {
|
||||
// Order is important for the local declaration deduplication
|
||||
val names = mutableSetOf<JsName>()
|
||||
|
||||
object : RecursiveJsVisitor() {
|
||||
|
||||
+5
@@ -4060,6 +4060,11 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/inline/lambdaReassignmentWithCapture.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclarationsClash.kt")
|
||||
public void testLocalDeclarationsClash() throws Exception {
|
||||
runTest("js/js.translator/testData/box/inline/localDeclarationsClash.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInlineExtensionFunction.kt")
|
||||
public void testLocalInlineExtensionFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/box/inline/localInlineExtensionFunction.kt");
|
||||
|
||||
+5
@@ -4060,6 +4060,11 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest {
|
||||
runTest("js/js.translator/testData/box/inline/lambdaReassignmentWithCapture.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclarationsClash.kt")
|
||||
public void testLocalDeclarationsClash() throws Exception {
|
||||
runTest("js/js.translator/testData/box/inline/localDeclarationsClash.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("localInlineExtensionFunction.kt")
|
||||
public void testLocalInlineExtensionFunction() throws Exception {
|
||||
runTest("js/js.translator/testData/box/inline/localInlineExtensionFunction.kt");
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
// EXPECTED_REACHABLE_NODES: 1281
|
||||
// FILE: 1.kt
|
||||
|
||||
package o
|
||||
|
||||
import I
|
||||
|
||||
inline fun run(): String {
|
||||
return object : I {
|
||||
override fun run() = "O"
|
||||
}.run()
|
||||
}
|
||||
|
||||
|
||||
// FILE: 2.kt
|
||||
|
||||
package k
|
||||
|
||||
import I
|
||||
|
||||
inline fun run(): String {
|
||||
return object : I {
|
||||
override fun run() = "K"
|
||||
}.run()
|
||||
}
|
||||
|
||||
// FILE: 3.kt
|
||||
|
||||
fun ok() = o.run() + k.run()
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
interface I {
|
||||
fun run(): String
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
if (ok() != "OK") return "fail"
|
||||
|
||||
|
||||
return o.run() + k.run()
|
||||
}
|
||||
Reference in New Issue
Block a user