JS: support module imports in new pipeline

This commit is contained in:
Alexey Andreev
2017-02-10 19:02:07 +03:00
parent 2354adfa22
commit a414cd64c5
4 changed files with 36 additions and 26 deletions
@@ -121,8 +121,6 @@ public final class StaticContext {
@NotNull
private final Map<JsImportedModuleKey, JsImportedModule> importedModules = new LinkedHashMap<>();
private Collection<JsImportedModule> readOnlyImportedModules;
@NotNull
private final JsScope rootPackageScope;
@@ -153,8 +151,7 @@ public final class StaticContext {
rootPackageScope = new JsObjectScope(rootScope, "<root package>");
JsName kotlinName = rootScope.declareName(Namer.KOTLIN_NAME);
importedModules.put(new JsImportedModuleKey(Namer.KOTLIN_LOWER_NAME, null),
new JsImportedModule(Namer.KOTLIN_LOWER_NAME, kotlinName, null));
createImportedModule(new JsImportedModuleKey(Namer.KOTLIN_LOWER_NAME, null), Namer.KOTLIN_LOWER_NAME, kotlinName, null);
classModelGenerator = new ClassModelGenerator(this);
}
@@ -189,14 +186,6 @@ public final class StaticContext {
return namer;
}
@NotNull
public Collection<JsImportedModule> getImportedModules() {
if (readOnlyImportedModules == null) {
readOnlyImportedModules = Collections.unmodifiableCollection(importedModules.values());
}
return readOnlyImportedModules;
}
@NotNull
public JsScope getScopeForDescriptor(@NotNull DeclarationDescriptor descriptor) {
if (descriptor instanceof ModuleDescriptor) {
@@ -526,7 +515,12 @@ public final class StaticContext {
public ObjectInstanceNameGenerator() {
addRule(descriptor -> {
String suggested = getSuggestedName(descriptor) + Namer.OBJECT_INSTANCE_FUNCTION_SUFFIX;
return localOrImportedName(descriptor, suggested);
JsName result = JsScope.declareTemporaryName(suggested);
String tag = SignatureUtilsKt.generateSignature(descriptor);
if (tag != null) {
fragment.getNameBindings().add(new JsNameBinding("object:" + tag, result));
}
return result;
});
}
}
@@ -681,12 +675,18 @@ public final class StaticContext {
JsImportedModule module = importedModules.get(key);
if (module == null) {
JsName internalName = rootScope.declareTemporaryName(Namer.LOCAL_MODULE_PREFIX + Namer.suggestedModuleName(baseName));
module = new JsImportedModule(baseName, internalName, plainName != null ? pureFqn(plainName, null) : null);
importedModules.put(key, module);
module = createImportedModule(key, baseName, internalName, plainName != null ? pureFqn(plainName, null) : null);
}
return module;
}
private JsImportedModule createImportedModule(JsImportedModuleKey key, String baseName, JsName internalName, JsExpression plainName) {
JsImportedModule module = new JsImportedModule(baseName, internalName, plainName);
importedModules.put(key, module);
fragment.getImportedModules().add(module);
return module;
}
@NotNull
private String getPlainId(@NotNull DeclarationDescriptor declaration) {
SuggestedName suggestedName = nameSuggestion.suggest(declaration);
@@ -125,11 +125,6 @@ public class TranslationContext {
return null;
}
@NotNull
public Collection<JsImportedModule> getImportedModules() {
return staticContext.getImportedModules();
}
@Nullable
public UsageTracker usageTracker() {
return usageTracker;
@@ -18,19 +18,20 @@ package org.jetbrains.kotlin.js.translate.general
import org.jetbrains.kotlin.js.backend.ast.*
import org.jetbrains.kotlin.js.backend.ast.metadata.coroutineMetadata
import org.jetbrains.kotlin.js.inline.clean.resolveTemporaryNames
import org.jetbrains.kotlin.js.translate.context.Namer
import org.jetbrains.kotlin.js.translate.utils.JsAstUtils
class Merger(private val rootFunction: JsFunction, val internalModuleName: JsName) {
// Maps unique signature (see generateSignature) to names
private val nameTable = mutableMapOf<String, JsName>()
private val importedModuleTable = mutableMapOf<JsImportedModuleKey, JsName>()
private val importBlock = JsGlobalBlock()
private val declarationBlock = JsGlobalBlock()
private val initializerBlock = JsGlobalBlock()
private val exportBlock = JsGlobalBlock()
private val declaredImports = mutableSetOf<String>()
private val classes = mutableMapOf<JsName, JsClassModel>()
private val importedModulesImpl = mutableListOf<JsImportedModule>()
// Add declaration and initialization statements from program fragment to resulting single program
fun addFragment(fragment: JsProgramFragment) {
@@ -49,6 +50,9 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam
exportBlock.statements += fragment.exportBlock
}
val importedModules: List<JsImportedModule>
get() = importedModulesImpl
private fun Map<JsName, JsName>.rename(name: JsName): JsName = getOrElse(name) { name }
// Builds mapping to map names from different fragments into single name when they denote single declaration
@@ -61,6 +65,19 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam
}
fragment.scope.findName(Namer.getRootPackageName())?.let { nameMap[it] = internalModuleName }
for (importedModule in fragment.importedModules) {
nameMap[importedModule.internalName] = importedModuleTable.getOrPut(importedModule.key) {
val scope = rootFunction.scope
val newName = importedModule.internalName.let {
if (it.isTemporary) scope.declareTemporaryName(it.ident) else scope.declareName(it.ident)
}
newName.also {
importedModulesImpl += JsImportedModule(importedModule.externalName, it, importedModule.plainReference)
it.copyMetadataFrom(importedModule.internalName)
}
}
}
return nameMap
}
@@ -99,7 +116,6 @@ class Merger(private val rootFunction: JsFunction, val internalModuleName: JsNam
this += declarationBlock.statements
this += initializerBlock.statements
}
rootFunction.body.resolveTemporaryNames()
}
private fun addClassPrototypes(statements: MutableList<JsStatement>) {
@@ -292,14 +292,13 @@ public final class Translation {
// Invoke function passing modules as arguments
// This should help minifier tool to recognize references to these modules as local variables and make them shorter.
List<JsImportedModule> importedModuleList = new ArrayList<>();
List<JsImportedModule> importedModuleList = merger.getImportedModules();
/*
for (JsImportedModule importedModule : staticContext.getImportedModules()) {
for (JsImportedModule importedModule : importedModuleList) {
rootFunction.getParameters().add(new JsParameter(importedModule.getInternalName()));
importedModuleList.add(importedModule);
}
/*
if (mainCallParameters.shouldBeGenerated()) {
JsStatement statement = generateCallToMain(context, files, mainCallParameters.arguments());
if (statement != null) {