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