diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt index a740535d975..7a9a4b98742 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JsIrCompiler.kt @@ -145,7 +145,8 @@ class K2JsIrCompiler : CLICompiler() { ) if (pluginLoadResult != ExitCode.OK) return pluginLoadResult - val libraries = configureLibraries(arguments.libraries) + val libraries: List = configureLibraries(arguments.libraries) + val friendLibraries: List = configureLibraries(arguments.friendModules) configuration.put(JSConfigurationKeys.LIBRARIES, libraries) configuration.put(JSConfigurationKeys.TRANSITIVE_LIBRARIES, libraries) @@ -201,8 +202,20 @@ class K2JsIrCompiler : CLICompiler() { // TODO: Handle non-empty main call arguments val mainCallArguments = if (K2JsArgumentConstants.NO_CALL == arguments.main) null else emptyList() - val dependencies = libraries.flatMap { listOfNotNull(loadIrLibrary(it, messageCollector)) } - .distinctBy { it.moduleName } + val loadedLibrariesNames = mutableSetOf() + val dependencies = mutableListOf() + val friendDependencies = mutableListOf() + + 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() { configuration, immediateDependencies = dependencies, allDependencies = dependencies, + friendDependencies = friendDependencies, mainArguments = mainCallArguments ) @@ -230,6 +244,7 @@ class K2JsIrCompiler : CLICompiler() { configuration = config.configuration, immediateDependencies = dependencies, allDependencies = dependencies, + friendDependencies = friendDependencies, outputKlibPath = outputKlibPath ) } @@ -274,7 +289,6 @@ class K2JsIrCompiler : CLICompiler() { val friendPaths = friendModules .split(File.pathSeparator.toRegex()) .dropLastWhile { it.isEmpty() } - .toTypedArray() .filterNot { it.isEmpty() } configuration.put(JSConfigurationKeys.FRIEND_PATHS, friendPaths) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index 464694faca5..fc9a5c87f89 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -22,10 +22,11 @@ fun compile( phaseConfig: PhaseConfig = PhaseConfig(jsPhases), immediateDependencies: List, allDependencies: List, + friendDependencies: List, mainArguments: List? ): String { val (moduleFragment, dependencyModules, irBuiltIns, symbolTable, deserializer) = - loadIr(project, files, configuration, immediateDependencies, allDependencies) + loadIr(project, files, configuration, immediateDependencies, allDependencies, friendDependencies) val moduleDescriptor = moduleFragment.descriptor diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index 8e260154cb6..e5ea8404e13 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -73,9 +73,10 @@ fun generateKLib( configuration: CompilerConfiguration, immediateDependencies: List, allDependencies: List, + friendDependencies: List, 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, configuration: CompilerConfiguration, immediateDependencies: List, - allDependencies: List + allDependencies: List, + friendDependencies: List ): 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, val compilerConfiguration: CompilerConfiguration, immediateDependencies: List, - private val allDependencies: List + private val allDependencies: List, + private val friendDependencies: List ) { private val deserializedModuleParts: Map = 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 ) diff --git a/compiler/ir/serialization.js/test/GenerateIrRuntime.kt b/compiler/ir/serialization.js/test/GenerateIrRuntime.kt index f2b92b0c155..c8d1fd48202 100644 --- a/compiler/ir/serialization.js/test/GenerateIrRuntime.kt +++ b/compiler/ir/serialization.js/test/GenerateIrRuntime.kt @@ -73,6 +73,7 @@ fun buildKLib( configuration = buildConfiguration(environment, moduleName), immediateDependencies = dependencies, allDependencies = dependencies, + friendDependencies = emptyList(), outputKlibPath = outputPath ) } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt index a489a97aa68..0d74b49a40b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicIrBoxTest.kt @@ -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 ) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt index 931362df59d..94c80b331d2 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt @@ -558,25 +558,26 @@ open class Kotlin2JsCompile : AbstractKotlinCompile(), 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