From df4c7048d02eaf9d9115ae070d08afde284fc1a6 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 13 Feb 2017 16:19:48 +0300 Subject: [PATCH] JS: do not create duplicate local variables for packages --- .../ast/metadata/metadataProperties.kt | 2 ++ .../translate/context/DeclarationExporter.kt | 5 +++-- .../kotlin/js/translate/general/Merger.kt | 22 ++++++++++++++++++- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/metadata/metadataProperties.kt b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/metadata/metadataProperties.kt index 7fb2c10920e..b91b8218ba2 100644 --- a/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/metadata/metadataProperties.kt +++ b/js/js.ast/src/org/jetbrains/kotlin/js/backend/ast/metadata/metadataProperties.kt @@ -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. diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/DeclarationExporter.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/DeclarationExporter.kt index ee86d57a637..7636f2265dc 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/DeclarationExporter.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/context/DeclarationExporter.kt @@ -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() } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt index ab31fb96ea9..34031b74f05 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Merger.kt @@ -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() private val classes = mutableMapOf() private val importedModulesImpl = mutableListOf() + private val exportedPackages = mutableMapOf() // 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() + 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.rename(fragment: JsProgramFragment) { rename(fragment.declarationBlock) rename(fragment.exportBlock)