JS: fix import cleaner

The tag generated during the source file translation could differ from
the tag generated based on the import statement (e.g. "intrinsic:..."
during generation becomes "'Kotlin'...." later on).

This means that the same function imported from the start and imported
during inlining has different tags. Which makes duplicate import removal
trickier. The best solution would be to make sure the tag generation
algorithms are consistent.

Current solution: rewrite the tags in terms of the Inliner tag
generation algorithm right after the source file translation.

Also it seems that some `var` statements we treated as imports, even
though they were not. Supported this behavior for now.

TODO: Get rid of these workaround
This commit is contained in:
Anton Bannykh
2018-12-17 18:58:10 +03:00
parent c1fbeeb7d9
commit a1649e9e4d
6 changed files with 90 additions and 27 deletions
@@ -43,11 +43,8 @@ import java.io.IOException
import java.util.ArrayList
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.hasError
import org.jetbrains.kotlin.js.backend.ast.JsGlobalBlock
import org.jetbrains.kotlin.js.backend.ast.JsProgramFragment
import org.jetbrains.kotlin.js.coroutine.transformCoroutines
import org.jetbrains.kotlin.js.translate.general.AstGenerationResult
import org.jetbrains.kotlin.metadata.js.JsProtoBuf
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf
@@ -339,6 +339,7 @@ public final class Translation {
for (String tag : staticContext.getInlineFunctionTags()) {
inlineFunctionTagMap.put(tag, unit);
}
NormalizeImportTagsKt.normalizeImportTags(fragment);
fragment.setTests(mayBeGenerateTests(context, file, fileMemberScope));
fragment.setMainFunction(maybeGenerateCallToMain(context, config, moduleDescriptor, fileMemberScope, mainCallParameters));
@@ -0,0 +1,36 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.translate.general
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsNameBinding
import org.jetbrains.kotlin.js.backend.ast.JsProgramFragment
import org.jetbrains.kotlin.js.inline.util.extractImportTag
// TODO this is a hack for `intrinsic:` tags
fun JsProgramFragment.normalizeImportTags() {
val newImports = mutableMapOf<String, JsExpression>()
val replacements = mutableMapOf<String, String>()
imports.entries.retainAll { (tag, statement) ->
extractImportTag(statement)?.let { newTag ->
if (newTag != tag) {
newImports[newTag] = statement
replacements[tag] = newTag
}
newTag == tag
} ?: true
}
imports += newImports
nameBindings.replaceAll { binding ->
replacements[binding.key]?.let {
JsNameBinding(it, binding.name)
} ?: binding
}
}