[JS IR BE] Support friend modules

This commit is contained in:
Svyatoslav Kuzmich
2019-05-08 17:59:36 +03:00
parent ad02700200
commit f4bb1354c9
6 changed files with 40 additions and 18 deletions
@@ -145,7 +145,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
)
if (pluginLoadResult != ExitCode.OK) return pluginLoadResult
val libraries = configureLibraries(arguments.libraries)
val libraries: List<String> = configureLibraries(arguments.libraries)
val friendLibraries: List<String> = configureLibraries(arguments.friendModules)
configuration.put(JSConfigurationKeys.LIBRARIES, libraries)
configuration.put(JSConfigurationKeys.TRANSITIVE_LIBRARIES, libraries)
@@ -201,8 +202,20 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
// TODO: Handle non-empty main call arguments
val mainCallArguments = if (K2JsArgumentConstants.NO_CALL == arguments.main) null else emptyList<String>()
val dependencies = libraries.flatMap { listOfNotNull(loadIrLibrary(it, messageCollector)) }
.distinctBy { it.moduleName }
val loadedLibrariesNames = mutableSetOf<String>()
val dependencies = mutableListOf<KlibModuleRef>()
val friendDependencies = mutableListOf<KlibModuleRef>()
for (library in libraries) {
val irLib = loadIrLibrary(library, messageCollector) ?: continue
if (irLib.moduleName !in loadedLibrariesNames) {
dependencies.add(irLib)
loadedLibrariesNames.add(irLib.moduleName)
if (library in friendLibraries) {
friendDependencies.add(irLib)
}
}
}
val produceKind = produceMap[arguments.irProduceOnly]
if (produceKind == null) {
@@ -216,6 +229,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
configuration,
immediateDependencies = dependencies,
allDependencies = dependencies,
friendDependencies = friendDependencies,
mainArguments = mainCallArguments
)
@@ -230,6 +244,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
configuration = config.configuration,
immediateDependencies = dependencies,
allDependencies = dependencies,
friendDependencies = friendDependencies,
outputKlibPath = outputKlibPath
)
}
@@ -274,7 +289,6 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
val friendPaths = friendModules
.split(File.pathSeparator.toRegex())
.dropLastWhile { it.isEmpty() }
.toTypedArray()
.filterNot { it.isEmpty() }
configuration.put(JSConfigurationKeys.FRIEND_PATHS, friendPaths)
@@ -22,10 +22,11 @@ fun compile(
phaseConfig: PhaseConfig = PhaseConfig(jsPhases),
immediateDependencies: List<KlibModuleRef>,
allDependencies: List<KlibModuleRef>,
friendDependencies: List<KlibModuleRef>,
mainArguments: List<String>?
): String {
val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) =
loadIr(project, files, configuration, immediateDependencies, allDependencies)
loadIr(project, files, configuration, immediateDependencies, allDependencies, friendDependencies)
val moduleDescriptor = moduleFragment.descriptor
@@ -73,9 +73,10 @@ fun generateKLib(
configuration: CompilerConfiguration,
immediateDependencies: List<KlibModuleRef>,
allDependencies: List<KlibModuleRef>,
friendDependencies: List<KlibModuleRef>,
outputKlibPath: String
): KlibModuleRef {
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies)
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies, friendDependencies)
val psi2IrContext = runAnalysisAndPreparePsi2Ir(depsDescriptors)
@@ -108,9 +109,10 @@ fun loadIr(
files: List<KtFile>,
configuration: CompilerConfiguration,
immediateDependencies: List<KlibModuleRef>,
allDependencies: List<KlibModuleRef>
allDependencies: List<KlibModuleRef>,
friendDependencies: List<KlibModuleRef>
): IrModuleInfo {
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies)
val depsDescriptors = ModulesStructure(project, files, configuration, immediateDependencies, allDependencies, friendDependencies)
val psi2IrContext = runAnalysisAndPreparePsi2Ir(depsDescriptors)
@@ -197,7 +199,8 @@ private class ModulesStructure(
private val files: List<KtFile>,
val compilerConfiguration: CompilerConfiguration,
immediateDependencies: List<KlibModuleRef>,
private val allDependencies: List<KlibModuleRef>
private val allDependencies: List<KlibModuleRef>,
private val friendDependencies: List<KlibModuleRef>
) {
private val deserializedModuleParts: Map<KlibModuleRef, JsKlibMetadataParts> =
allDependencies.associateWith { loadKlibMetadataParts(it) }
@@ -223,7 +226,7 @@ private class ModulesStructure(
project,
compilerConfiguration,
sortedImmediateDependencies.map { getModuleDescriptor(it) },
friendModuleDescriptors = emptyList(),
friendModuleDescriptors = friendDependencies.map { getModuleDescriptor(it) },
thisIsBuiltInsModule = builtInModuleDescriptor == null,
customBuiltInsModule = builtInModuleDescriptor
)
@@ -73,6 +73,7 @@ fun buildKLib(
configuration = buildConfiguration(environment, moduleName),
immediateDependencies = dependencies,
allDependencies = dependencies,
friendDependencies = emptyList(),
outputKlibPath = outputPath
)
}
@@ -97,6 +97,7 @@ abstract class BasicIrBoxTest(
phaseConfig = config.configuration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jsPhases),
immediateDependencies = dependencies,
allDependencies = allDependencies,
friendDependencies = emptyList(),
mainArguments = mainCallParameters.run { if (shouldBeGenerated()) arguments() else null }
)
@@ -110,6 +111,7 @@ abstract class BasicIrBoxTest(
configuration = config.configuration,
immediateDependencies = dependencies,
allDependencies = allDependencies,
friendDependencies = emptyList(),
outputKlibPath = actualOutputFile
)
@@ -558,25 +558,26 @@ open class Kotlin2JsCompile : AbstractKotlinCompile<K2JSCompilerArguments>(), Ko
get() = friendTaskName
?.let { project.getTasksByName(it, false).singleOrNull() as? Kotlin2JsCompile }
?.outputFile?.parentFile
?.let { if (LibraryUtils.isKotlinJavascriptLibrary(it)) it else null }
?.let { if (libraryFilter(it)) it else null }
?.absolutePath
private val libraryFilter: (File) -> Boolean
get() = if ("-Xir" in kotlinOptions.freeCompilerArgs) {
// TODO: Detect IR libraries
{ true }
} else {
LibraryUtils::isKotlinJavascriptLibrary
}
override fun callCompilerAsync(args: K2JSCompilerArguments, sourceRoots: SourceRoots, changedFiles: ChangedFiles) {
sourceRoots as SourceRoots.KotlinOnly
logger.debug("Calling compiler")
destinationDir.mkdirs()
val libraryFilter: (File) -> Boolean
if ("-Xir" in args.freeArgs) {
logger.kotlinDebug("Using JS IR backend")
incremental = false
// TODO: Detect IR libraries
libraryFilter = { true }
} else {
libraryFilter = LibraryUtils::isKotlinJavascriptLibrary
}
val dependencies = compileClasspath