JS: do not create duplicate local variables for packages

This commit is contained in:
Alexey Andreev
2017-02-13 16:19:48 +03:00
parent cb8189989c
commit df4c7048d0
3 changed files with 26 additions and 3 deletions
@@ -52,6 +52,8 @@ var JsInvocation.typeCheck: TypeCheck? by MetadataProperty(default = null)
var JsInvocation.boxing: Boolean by MetadataProperty(default = false)
var JsVars.exportedPackage: String? by MetadataProperty(default = null)
/**
* For function and lambda bodies indicates what declaration corresponds to.
* When absent (`null`) on body of a named function, this function is from external JS module.
@@ -16,10 +16,11 @@
package org.jetbrains.kotlin.js.translate.context
import org.jetbrains.kotlin.js.backend.ast.metadata.staticRef
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnlyOrReifiable
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.backend.ast.metadata.exportedPackage
import org.jetbrains.kotlin.js.backend.ast.metadata.staticRef
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isLibraryObject
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils.isNativeObject
@@ -137,7 +138,7 @@ internal class DeclarationExporter(val context: StaticContext) {
val selfRef = JsNameRef(packageName.shortName().asString(), parentRef)
val rhs = JsAstUtils.or(selfRef, assignment(selfRef.deepCopy(), JsObjectLiteral(false)))
statements.add(JsAstUtils.newVar(name, rhs))
statements.add(JsAstUtils.newVar(name, rhs).apply { exportedPackage = packageName.asString() })
}
return name.makeRef()
}
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.js.translate.general
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.backend.ast.metadata.coroutineMetadata
import org.jetbrains.kotlin.js.backend.ast.metadata.exportedPackage
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
@@ -33,6 +34,7 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam
private val declaredImports = mutableSetOf<String>()
private val classes = mutableMapOf<JsName, JsClassModel>()
private val importedModulesImpl = mutableListOf<JsImportedModule>()
private val exportedPackages = mutableMapOf<String, JsName>()
// Add declaration and initialization statements from program fragment to resulting single program
fun addFragment(fragment: JsProgramFragment) {
@@ -48,7 +50,7 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam
declarationBlock.statements += fragment.declarationBlock
initializerBlock.statements += fragment.initializerBlock
exportBlock.statements += fragment.exportBlock
addExportStatements(fragment)
classes += fragment.classes.values.map { cls ->
val name = nameMap.rename(cls.name)
@@ -89,6 +91,24 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam
return nameMap
}
private fun addExportStatements(fragment: JsProgramFragment) {
val nameMap = mutableMapOf<JsName, JsName>()
for (statement in fragment.exportBlock.statements) {
if (statement is JsVars && statement.exportedPackage != null) {
val exportedPackage = statement.exportedPackage!!
val localName = statement.vars[0].name
if (exportedPackage in exportedPackages) {
nameMap[localName] = exportedPackages[exportedPackage]!!
continue
}
else {
exportedPackages[exportedPackage] = localName
}
}
exportBlock.statements += nameMap.rename(statement)
}
}
private fun Map<JsName, JsName>.rename(fragment: JsProgramFragment) {
rename(fragment.declarationBlock)
rename(fragment.exportBlock)