[JS] Implementation dependencies for JS klibs

^KT-56158 fixed
This commit is contained in:
Ilya Goncharov
2023-01-27 13:31:59 +00:00
committed by Space Team
parent ca0b3ffa78
commit 1150ec6882
22 changed files with 128 additions and 72 deletions
@@ -56,13 +56,6 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
) )
var libraries: String? by NullableStringFreezableVar(null) var libraries: String? by NullableStringFreezableVar(null)
@Argument(
value = "-Xrepositories",
valueDescription = "<path>",
description = "Paths to additional places where libraries could be found"
)
var repositries: String? by NullableStringFreezableVar(null)
@GradleOption( @GradleOption(
value = DefaultValue.BOOLEAN_FALSE_DEFAULT, value = DefaultValue.BOOLEAN_FALSE_DEFAULT,
gradleInputType = GradleInputTypes.INPUT, gradleInputType = GradleInputTypes.INPUT,
@@ -193,11 +193,9 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
val libraries: List<String> = configureLibraries(arguments.libraries) + listOfNotNull(arguments.includes) val libraries: List<String> = configureLibraries(arguments.libraries) + listOfNotNull(arguments.includes)
val friendLibraries: List<String> = configureLibraries(arguments.friendModules) val friendLibraries: List<String> = configureLibraries(arguments.friendModules)
val repositories: List<String> = configureLibraries(arguments.repositries)
configuration.put(JSConfigurationKeys.LIBRARIES, libraries) configuration.put(JSConfigurationKeys.LIBRARIES, libraries)
configuration.put(JSConfigurationKeys.TRANSITIVE_LIBRARIES, libraries) configuration.put(JSConfigurationKeys.TRANSITIVE_LIBRARIES, libraries)
configuration.put(JSConfigurationKeys.REPOSITORIES, repositories)
configuration.put(JSConfigurationKeys.PARTIAL_LINKAGE, arguments.partialLinkage) configuration.put(JSConfigurationKeys.PARTIAL_LINKAGE, arguments.partialLinkage)
@@ -449,7 +447,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
moduleSourceFiles, moduleSourceFiles,
environmentForJS.configuration, environmentForJS.configuration,
sourceModule.jsFrontEndResult.jsAnalysisResult, sourceModule.jsFrontEndResult.jsAnalysisResult,
sortDependencies(sourceModule.moduleDependencies), sourceModule.allDependencies,
icData, icData,
expectDescriptorToSymbol, expectDescriptorToSymbol,
IrFactoryImpl, IrFactoryImpl,
@@ -514,9 +512,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
// TODO: !!! dependencies module data? // TODO: !!! dependencies module data?
} }
val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList()
val logger = configuration.resolverLogger val logger = configuration.resolverLogger
val resolvedLibraries = jsResolveLibraries(libraries + friendLibraries, repositories, logger).getFullResolvedList() val resolvedLibraries = jsResolveLibraries(libraries + friendLibraries, logger).getFullResolvedList()
FirJsSessionFactory.createJsLibrarySession( FirJsSessionFactory.createJsLibrarySession(
mainModuleName, mainModuleName,
@@ -25,7 +25,6 @@ abstract class AbstractIncrementalMultiModuleJsKlibCompilerRunnerTest :
irProduceKlibDir = false irProduceKlibDir = false
irProduceKlibFile = true irProduceKlibFile = true
irOnly = true irOnly = true
repositries = repository.absolutePath
} }
override val buildLogFinder: BuildLogFinder override val buildLogFinder: BuildLogFinder
@@ -88,8 +88,7 @@ class CacheUpdater(
// libraries in topological order: [stdlib, ..., main] // libraries in topological order: [stdlib, ..., main]
val libraryDependencies = stopwatch.measure("Resolving and loading klib dependencies") { val libraryDependencies = stopwatch.measure("Resolving and loading klib dependencies") {
val repositories = compilerConfiguration[JSConfigurationKeys.REPOSITORIES] ?: emptyList() val allResolvedDependencies = jsResolveLibraries(allModules, compilerConfiguration.resolverLogger)
val allResolvedDependencies = jsResolveLibraries(allModules, repositories, compilerConfiguration.resolverLogger)
val libraries = allResolvedDependencies.getFullList(TopologicalLibraryOrder).let { resolvedLibraries -> val libraries = allResolvedDependencies.getFullList(TopologicalLibraryOrder).let { resolvedLibraries ->
val mainLibraryIndex = resolvedLibraries.indexOfLast { val mainLibraryIndex = resolvedLibraries.indexOfLast {
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.library.KotlinLibraryProperResolverWithAttributes
import org.jetbrains.kotlin.library.UnresolvedLibrary import org.jetbrains.kotlin.library.UnresolvedLibrary
import org.jetbrains.kotlin.library.impl.createKotlinLibraryComponents import org.jetbrains.kotlin.library.impl.createKotlinLibraryComponents
import org.jetbrains.kotlin.library.metadata.resolver.KotlinLibraryResolveResult import org.jetbrains.kotlin.library.metadata.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.library.metadata.resolver.KotlinLibraryResolver
import org.jetbrains.kotlin.library.metadata.resolver.impl.libraryResolver import org.jetbrains.kotlin.library.metadata.resolver.impl.libraryResolver
import org.jetbrains.kotlin.util.Logger import org.jetbrains.kotlin.util.Logger
@@ -35,24 +36,46 @@ class JsLibraryResolver(
} }
// TODO: This is a temporary set of library resolver policies for js compiler. // TODO: This is a temporary set of library resolver policies for js compiler.
fun jsResolveLibraries(libraries: Collection<String>, repositories: Collection<String>, logger: Logger): KotlinLibraryResolveResult { fun jsResolveLibraries(libraries: Collection<String>, logger: Logger): KotlinLibraryResolveResult =
jsResolveLibrariesWithoutDependencies(
libraries,
logger
).resolveWithDependencies()
fun jsResolveLibrariesWithoutDependencies(
libraries: Collection<String>,
logger: Logger
): JsResolution {
val unresolvedLibraries = libraries.map { UnresolvedLibrary(it, null) } val unresolvedLibraries = libraries.map { UnresolvedLibrary(it, null) }
val libraryAbsolutePaths = libraries.map { File(it).absolutePath } val libraryAbsolutePaths = libraries.map { File(it).absolutePath }
// Configure the resolver to only work with absolute paths for now. // Configure the resolver to only work with absolute paths for now.
val libraryResolver = JsLibraryResolver( val libraryResolver = JsLibraryResolver(
repositories = repositories.toList(), repositories = emptyList(),
directLibs = libraryAbsolutePaths, directLibs = libraryAbsolutePaths,
distributionKlib = null, distributionKlib = null,
localKotlinDir = null, localKotlinDir = null,
skipCurrentDir = false, skipCurrentDir = false,
logger = logger logger = logger
).libraryResolver() ).libraryResolver()
val resolvedLibraries =
libraryResolver.resolveWithDependencies( return JsResolution(
libraryResolver,
libraryResolver.resolveWithoutDependencies(
unresolvedLibraries = unresolvedLibraries, unresolvedLibraries = unresolvedLibraries,
noStdLib = true, noStdLib = true,
noDefaultLibs = true, noDefaultLibs = true,
noEndorsedLibs = true noEndorsedLibs = true
) )
return resolvedLibraries )
} }
class JsResolution(
private val libraryResolver: KotlinLibraryResolver<KotlinLibrary>,
val libraries: List<KotlinLibrary>
) {
fun resolveWithDependencies(): KotlinLibraryResolveResult {
return with(libraryResolver) {
libraries.resolveDependencies()
}
}
}
@@ -128,7 +128,7 @@ fun generateKLib(
) { ) {
val files = (depsDescriptors.mainModule as MainModule.SourceFiles).files.map(::KtPsiSourceFile) val files = (depsDescriptors.mainModule as MainModule.SourceFiles).files.map(::KtPsiSourceFile)
val configuration = depsDescriptors.compilerConfiguration val configuration = depsDescriptors.compilerConfiguration
val allDependencies = depsDescriptors.allDependencies.map { it.library } val allDependencies = depsDescriptors.allDependencies
val messageLogger = configuration.irMessageLogger val messageLogger = configuration.irMessageLogger
serializeModuleIntoKlib( serializeModuleIntoKlib(
@@ -202,7 +202,7 @@ fun loadIr(
val project = depsDescriptors.project val project = depsDescriptors.project
val mainModule = depsDescriptors.mainModule val mainModule = depsDescriptors.mainModule
val configuration = depsDescriptors.compilerConfiguration val configuration = depsDescriptors.compilerConfiguration
val allDependencies = depsDescriptors.allDependencies.map { it.library } val allDependencies = depsDescriptors.allDependencies
val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT val errorPolicy = configuration.get(JSConfigurationKeys.ERROR_TOLERANCE_POLICY) ?: ErrorTolerancePolicy.DEFAULT
val messageLogger = configuration.irMessageLogger val messageLogger = configuration.irMessageLogger
val partialLinkageEnabled = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false val partialLinkageEnabled = configuration[JSConfigurationKeys.PARTIAL_LINKAGE] ?: false
@@ -215,7 +215,7 @@ fun loadIr(
assert(filesToLoad == null) assert(filesToLoad == null)
val psi2IrContext = preparePsi2Ir(depsDescriptors, errorPolicy, symbolTable, partialLinkageEnabled) val psi2IrContext = preparePsi2Ir(depsDescriptors, errorPolicy, symbolTable, partialLinkageEnabled)
val friendModules = val friendModules =
mapOf(psi2IrContext.moduleDescriptor.name.asString() to depsDescriptors.friendDependencies.map { it.library.uniqueName }) mapOf(psi2IrContext.moduleDescriptor.name.asString() to depsDescriptors.friendDependencies.map { it.uniqueName })
return getIrModuleInfoForSourceFiles( return getIrModuleInfoForSourceFiles(
psi2IrContext, psi2IrContext,
@@ -236,7 +236,7 @@ fun loadIr(
?: error("No module with ${mainModule.libPath} found") ?: error("No module with ${mainModule.libPath} found")
val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModuleLib) val moduleDescriptor = depsDescriptors.getModuleDescriptor(mainModuleLib)
val sortedDependencies = sortDependencies(depsDescriptors.moduleDependencies) val sortedDependencies = sortDependencies(depsDescriptors.moduleDependencies)
val friendModules = mapOf(mainModuleLib.uniqueName to depsDescriptors.friendDependencies.map { it.library.uniqueName }) val friendModules = mapOf(mainModuleLib.uniqueName to depsDescriptors.friendDependencies.map { it.uniqueName })
return getIrModuleInfoForKlib( return getIrModuleInfoForKlib(
moduleDescriptor, moduleDescriptor,
@@ -474,29 +474,29 @@ class ModulesStructure(
friendDependenciesPaths: Collection<String>, friendDependenciesPaths: Collection<String>,
) { ) {
val allResolvedDependencies = jsResolveLibraries( val allDependenciesResolution = jsResolveLibrariesWithoutDependencies(
dependencies, dependencies,
compilerConfiguration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
compilerConfiguration.resolverLogger compilerConfiguration.resolverLogger
) )
val allDependencies = allResolvedDependencies.getFullResolvedList() val allDependencies: List<KotlinLibrary>
get() = allDependenciesResolution.libraries
val friendDependencies = allDependencies.run { val friendDependencies = allDependencies.run {
val friendAbsolutePaths = friendDependenciesPaths.map { File(it).canonicalPath } val friendAbsolutePaths = friendDependenciesPaths.map { File(it).canonicalPath }
filter { filter {
it.library.libraryFile.absolutePath in friendAbsolutePaths it.libraryFile.absolutePath in friendAbsolutePaths
} }
} }
val moduleDependencies: Map<KotlinLibrary, List<KotlinLibrary>> = run { val moduleDependencies: Map<KotlinLibrary, List<KotlinLibrary>> by lazy {
val transitives = allDependencies val transitives = allDependenciesResolution.resolveWithDependencies().getFullResolvedList()
transitives.associate { klib -> transitives.associate { klib ->
klib.library to klib.resolvedDependencies.map { d -> d.library } klib.library to klib.resolvedDependencies.map { d -> d.library }
}.toMap() }.toMap()
} }
private val builtInsDep = allDependencies.find { it.library.isBuiltIns } private val builtInsDep = allDependencies.find { it.isBuiltIns }
class JsFrontEndResult(val jsAnalysisResult: AnalysisResult, val hasErrors: Boolean) { class JsFrontEndResult(val jsAnalysisResult: AnalysisResult, val hasErrors: Boolean) {
val moduleDescriptor: ModuleDescriptor val moduleDescriptor: ModuleDescriptor
@@ -508,7 +508,11 @@ class ModulesStructure(
lateinit var jsFrontEndResult: JsFrontEndResult lateinit var jsFrontEndResult: JsFrontEndResult
fun runAnalysis(errorPolicy: ErrorTolerancePolicy, analyzer: AbstractAnalyzerWithCompilerReport, analyzerFacade: AbstractTopDownAnalyzerFacadeForJS) { fun runAnalysis(
errorPolicy: ErrorTolerancePolicy,
analyzer: AbstractAnalyzerWithCompilerReport,
analyzerFacade: AbstractTopDownAnalyzerFacadeForJS
) {
require(mainModule is MainModule.SourceFiles) require(mainModule is MainModule.SourceFiles)
val files = mainModule.files val files = mainModule.files
@@ -517,8 +521,8 @@ class ModulesStructure(
files, files,
project, project,
compilerConfiguration, compilerConfiguration,
allModuleDescriptors, descriptors.values.toList(),
friendDependencies.map { getModuleDescriptor(it.library) }, friendDependencies.map { getModuleDescriptor(it) },
analyzer.targetEnvironment, analyzer.targetEnvironment,
thisIsBuiltInsModule = builtInModuleDescriptor == null, thisIsBuiltInsModule = builtInModuleDescriptor == null,
customBuiltInsModule = builtInModuleDescriptor customBuiltInsModule = builtInModuleDescriptor
@@ -550,22 +554,23 @@ class ModulesStructure(
private val storageManager: LockBasedStorageManager = LockBasedStorageManager("ModulesStructure") private val storageManager: LockBasedStorageManager = LockBasedStorageManager("ModulesStructure")
private var runtimeModule: ModuleDescriptorImpl? = null private var runtimeModule: ModuleDescriptorImpl? = null
// TODO: these are roughly equivalent to KlibResolvedModuleDescriptorsFactoryImpl. Refactor me. private val _descriptors: MutableMap<KotlinLibrary, ModuleDescriptorImpl> = mutableMapOf()
val descriptors = mutableMapOf<KotlinLibrary, ModuleDescriptorImpl>()
val allModuleDescriptors = run { init {
val descriptors = allDependencies.map { getModuleDescriptor(it.library) } val descriptors = allDependencies.map { getModuleDescriptorImpl(it) }
descriptors.forEach { descriptor -> descriptors.forEach { descriptor ->
descriptor.setDependencies(descriptors) descriptor.setDependencies(descriptors)
} }
descriptors
} }
fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptorImpl { // TODO: these are roughly equivalent to KlibResolvedModuleDescriptorsFactoryImpl. Refactor me.
if (current in descriptors) { val descriptors: Map<KotlinLibrary, ModuleDescriptor>
return descriptors.getValue(current) get() = _descriptors
private fun getModuleDescriptorImpl(current: KotlinLibrary): ModuleDescriptorImpl {
if (current in _descriptors) {
return _descriptors.getValue(current)
} }
val isBuiltIns = current.unresolvedDependencies.isEmpty() val isBuiltIns = current.unresolvedDependencies.isEmpty()
@@ -581,14 +586,17 @@ class ModulesStructure(
) )
if (isBuiltIns) runtimeModule = md if (isBuiltIns) runtimeModule = md
descriptors[current] = md _descriptors[current] = md
return md return md
} }
fun getModuleDescriptor(current: KotlinLibrary): ModuleDescriptor =
getModuleDescriptorImpl(current)
val builtInModuleDescriptor = val builtInModuleDescriptor =
if (builtInsDep != null) if (builtInsDep != null)
getModuleDescriptor(builtInsDep.library) getModuleDescriptor(builtInsDep)
else else
null // null in case compiling builtInModule itself null // null in case compiling builtInModule itself
} }
-1
View File
@@ -40,7 +40,6 @@ where advanced options include:
-Xlegacy-deprecated-no-warn Disable warnings of deprecation of legacy compiler -Xlegacy-deprecated-no-warn Disable warnings of deprecation of legacy compiler
-Xmetadata-only Generate *.meta.js and *.kjsm files only -Xmetadata-only Generate *.meta.js and *.kjsm files only
-Xpartial-linkage Allow unlinked symbols -Xpartial-linkage Allow unlinked symbols
-Xrepositories=<path> Paths to additional places where libraries could be found
-Xstrict-implicit-export-types Generate strict types for implicitly exported entities inside d.ts files. Available in IR backend only. -Xstrict-implicit-export-types Generate strict types for implicitly exported entities inside d.ts files. Available in IR backend only.
-Xtyped-arrays Translate primitive arrays to JS typed arrays -Xtyped-arrays Translate primitive arrays to JS typed arrays
-Xuse-deprecated-legacy-compiler -Xuse-deprecated-legacy-compiler
@@ -256,7 +256,6 @@ class ClassicFrontendFacade(
private fun loadKlib(names: List<String>, configuration: CompilerConfiguration): List<ModuleDescriptor> { private fun loadKlib(names: List<String>, configuration: CompilerConfiguration): List<ModuleDescriptor> {
val resolvedLibraries = jsResolveLibraries( val resolvedLibraries = jsResolveLibraries(
names, names,
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
configuration.resolverLogger configuration.resolverLogger
).getFullResolvedList() ).getFullResolvedList()
@@ -37,10 +37,9 @@ object TestFirJsSessionFactory {
languageVersionSettings: LanguageVersionSettings, languageVersionSettings: LanguageVersionSettings,
registerExtraComponents: ((FirSession) -> Unit), registerExtraComponents: ((FirSession) -> Unit),
): FirSession { ): FirSession {
val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList()
val logger = configuration.resolverLogger val logger = configuration.resolverLogger
val libraries = getAllJsDependenciesPaths(module, testServices) val libraries = getAllJsDependenciesPaths(module, testServices)
val resolvedLibraries = jsResolveLibraries(libraries, repositories, logger).getFullResolvedList() val resolvedLibraries = jsResolveLibraries(libraries, logger).getFullResolvedList()
return FirJsSessionFactory.createJsLibrarySession( return FirJsSessionFactory.createJsLibrarySession(
mainModuleName, mainModuleName,
@@ -75,9 +74,8 @@ fun resolveJsLibraries(
configuration: CompilerConfiguration configuration: CompilerConfiguration
): List<KotlinResolvedLibrary> { ): List<KotlinResolvedLibrary> {
val paths = getAllJsDependenciesPaths(module, testServices) val paths = getAllJsDependenciesPaths(module, testServices)
val repositories = configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList()
val logger = configuration.resolverLogger val logger = configuration.resolverLogger
return jsResolveLibraries(paths, repositories, logger).getFullResolvedList() return jsResolveLibraries(paths, logger).getFullResolvedList()
} }
fun getAllJsDependenciesPaths(module: TestModule, testServices: TestServices): List<String> { fun getAllJsDependenciesPaths(module: TestModule, testServices: TestServices): List<String> {
@@ -236,7 +236,7 @@ abstract class AbstractKlibTextTestCase : CodegenTestCase() {
} }
private fun loadKlibFromPath(paths: List<String>): List<KotlinLibrary> { private fun loadKlibFromPath(paths: List<String>): List<KotlinLibrary> {
val result = jsResolveLibraries(paths, emptyList(), DummyLogger) val result = jsResolveLibraries(paths, DummyLogger)
return result.getFullList(TopologicalLibraryOrder) return result.getFullList(TopologicalLibraryOrder)
} }
@@ -102,7 +102,7 @@ class FilePathsInKlibTest : CodegenTestCase() {
private fun File.md5(): Long = readBytes().md5() private fun File.md5(): Long = readBytes().md5()
private fun File.loadKlibFilePaths(): List<String> { private fun File.loadKlibFilePaths(): List<String> {
val libs = jsResolveLibraries(listOf(runtimeKlibPath, canonicalPath), emptyList(), DummyLogger).getFullList() val libs = jsResolveLibraries(listOf(runtimeKlibPath, canonicalPath), DummyLogger).getFullList()
val lib = libs.last() val lib = libs.last()
val fileSize = lib.fileCount() val fileSize = lib.fileCount()
val extReg = ExtensionRegistryLite.newInstance() val extReg = ExtensionRegistryLite.newInstance()
@@ -18,7 +18,22 @@ interface KotlinLibraryResolver<L: KotlinLibrary> {
noStdLib: Boolean = false, noStdLib: Boolean = false,
noDefaultLibs: Boolean = false, noDefaultLibs: Boolean = false,
noEndorsedLibs: Boolean = false noEndorsedLibs: Boolean = false
): KotlinLibraryResolveResult ): KotlinLibraryResolveResult =
resolveWithoutDependencies(
unresolvedLibraries,
noStdLib,
noDefaultLibs,
noEndorsedLibs
).resolveDependencies()
fun resolveWithoutDependencies(
unresolvedLibraries: List<UnresolvedLibrary>,
noStdLib: Boolean = false,
noDefaultLibs: Boolean = false,
noEndorsedLibs: Boolean = false
): List<KotlinLibrary>
fun List<KotlinLibrary>.resolveDependencies(): KotlinLibraryResolveResult
} }
interface KotlinLibraryResolveResult { interface KotlinLibraryResolveResult {
@@ -32,16 +32,14 @@ class KotlinLibraryResolverImpl<L: KotlinLibrary> internal constructor(
override val searchPathResolver: SearchPathResolver<L>, override val searchPathResolver: SearchPathResolver<L>,
val resolveManifestDependenciesLenient: Boolean val resolveManifestDependenciesLenient: Boolean
): KotlinLibraryResolver<L>, WithLogger by searchPathResolver { ): KotlinLibraryResolver<L>, WithLogger by searchPathResolver {
override fun resolveWithoutDependencies(
override fun resolveWithDependencies(
unresolvedLibraries: List<UnresolvedLibrary>, unresolvedLibraries: List<UnresolvedLibrary>,
noStdLib: Boolean, noStdLib: Boolean,
noDefaultLibs: Boolean, noDefaultLibs: Boolean,
noEndorsedLibs: Boolean noEndorsedLibs: Boolean
) = findLibraries(unresolvedLibraries, noStdLib, noDefaultLibs, noEndorsedLibs) ) = findLibraries(unresolvedLibraries, noStdLib, noDefaultLibs, noEndorsedLibs)
.leaveDistinct() .leaveDistinct()
.omitDuplicateNames() .omitDuplicateNames()
.resolveDependencies()
/** /**
* Returns the list of libraries based on [libraryNames], [noStdLib], [noDefaultLibs] and [noEndorsedLibs] criteria. * Returns the list of libraries based on [libraryNames], [noStdLib], [noDefaultLibs] and [noEndorsedLibs] criteria.
@@ -102,7 +100,7 @@ class KotlinLibraryResolverImpl<L: KotlinLibrary> internal constructor(
* 2. Wraps each [KotlinLibrary] into a [KotlinResolvedLibrary] with information about dependencies on other libraries. * 2. Wraps each [KotlinLibrary] into a [KotlinResolvedLibrary] with information about dependencies on other libraries.
* 3. Creates resulting [KotlinLibraryResolveResult] object. * 3. Creates resulting [KotlinLibraryResolveResult] object.
*/ */
private fun List<KotlinLibrary>.resolveDependencies(): KotlinLibraryResolveResult { override fun List<KotlinLibrary>.resolveDependencies(): KotlinLibraryResolveResult {
val rootLibraries = this.map { KotlinResolvedLibraryImpl(it) } val rootLibraries = this.map { KotlinResolvedLibraryImpl(it) }
@@ -253,7 +253,6 @@ class CompilerArgumentsContentProspectorTest {
K2JSCompilerArguments::friendModules, K2JSCompilerArguments::friendModules,
K2JSCompilerArguments::errorTolerancePolicy, K2JSCompilerArguments::errorTolerancePolicy,
K2JSCompilerArguments::irDceRuntimeDiagnostic, K2JSCompilerArguments::irDceRuntimeDiagnostic,
K2JSCompilerArguments::repositries,
) )
private val k2JSCompilerArgumentsArrayProperties = commonCompilerArgumentsArrayProperties private val k2JSCompilerArgumentsArrayProperties = commonCompilerArgumentsArrayProperties
@@ -100,9 +100,6 @@ public class JSConfigurationKeys {
public static final CompilerConfigurationKey<ErrorTolerancePolicy> ERROR_TOLERANCE_POLICY = public static final CompilerConfigurationKey<ErrorTolerancePolicy> ERROR_TOLERANCE_POLICY =
CompilerConfigurationKey.create("set up policy to ignore compilation errors"); CompilerConfigurationKey.create("set up policy to ignore compilation errors");
public static final CompilerConfigurationKey<Collection<String>> REPOSITORIES =
CompilerConfigurationKey.create("set up additional repository paths");
public static final CompilerConfigurationKey<Boolean> PARTIAL_LINKAGE = public static final CompilerConfigurationKey<Boolean> PARTIAL_LINKAGE =
CompilerConfigurationKey.create("allows some symbols in klibs be missed"); CompilerConfigurationKey.create("allows some symbols in klibs be missed");
@@ -77,7 +77,6 @@ class FirJsKlibBackendFacade(
// TODO: consider avoiding repeated libraries resolution // TODO: consider avoiding repeated libraries resolution
val lib = jsResolveLibraries( val lib = jsResolveLibraries(
getAllJsDependenciesPaths(module, testServices) + listOf(outputFile), getAllJsDependenciesPaths(module, testServices) + listOf(outputFile),
emptyList(),
configuration.resolverLogger configuration.resolverLogger
).getFullResolvedList().last().library ).getFullResolvedList().last().library
@@ -71,7 +71,6 @@ class JsKlibBackendFacade(
val dependencies = JsEnvironmentConfigurator.getAllRecursiveDependenciesFor(module, testServices).toList() val dependencies = JsEnvironmentConfigurator.getAllRecursiveDependenciesFor(module, testServices).toList()
val lib = jsResolveLibraries( val lib = jsResolveLibraries(
dependencies.map { testServices.jsLibraryProvider.getPathByDescriptor(it) } + listOf(outputFile), dependencies.map { testServices.jsLibraryProvider.getPathByDescriptor(it) } + listOf(outputFile),
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
configuration.resolverLogger configuration.resolverLogger
).getFullResolvedList().last().library ).getFullResolvedList().last().library
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.js.testOld.V8JsTestChecker import org.jetbrains.kotlin.js.testOld.V8JsTestChecker
import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION import org.jetbrains.kotlin.library.KLIB_FILE_EXTENSION
import org.jetbrains.kotlin.test.KotlinBaseTest
import java.io.File import java.io.File
abstract class AbstractJsKlibBinaryCompatibilityTest : AbstractKlibBinaryCompatibilityTest() { abstract class AbstractJsKlibBinaryCompatibilityTest : AbstractKlibBinaryCompatibilityTest() {
@@ -32,7 +33,22 @@ abstract class AbstractJsKlibBinaryCompatibilityTest : AbstractKlibBinaryCompati
} }
private fun TestModule.dependenciesToLibrariesArg(version: Int): String = private fun TestModule.dependenciesToLibrariesArg(version: Int): String =
this.dependencies.map { it as? TestModule ?: error("Unexpected dependency kind: $it") }.toLibrariesArg(version) this.dependencies
.flatMap { it.transitiveDependencies() }
.map { it as? TestModule ?: error("Unexpected dependency kind: $it") }
.toLibrariesArg(version)
private fun KotlinBaseTest.TestModule.transitiveDependencies(): Set<KotlinBaseTest.TestModule> {
val uniqueDependencies = mutableSetOf(this)
dependencies.forEach { testModule ->
if (testModule !in uniqueDependencies) {
val transitiveDependencies = testModule.transitiveDependencies()
uniqueDependencies.addAll(transitiveDependencies)
}
}
return uniqueDependencies
}
private val TestModule.jsPath get() = File(workingDir, "${this.name}.js").absolutePath private val TestModule.jsPath get() = File(workingDir, "${this.name}.js").absolutePath
@@ -58,7 +74,6 @@ abstract class AbstractJsKlibBinaryCompatibilityTest : AbstractKlibBinaryCompati
irProduceKlibFile = true irProduceKlibFile = true
irOnly = true irOnly = true
irModuleName = module.name irModuleName = module.name
repositries = "$workingDir${File.pathSeparator}$workingDir/version$version"
} }
K2JSCompiler().exec(TestMessageCollector(), Services.EMPTY, args) K2JSCompiler().exec(TestMessageCollector(), Services.EMPTY, args)
} }
@@ -73,7 +88,6 @@ abstract class AbstractJsKlibBinaryCompatibilityTest : AbstractKlibBinaryCompati
irProduceJs = true irProduceJs = true
irOnly = true irOnly = true
irModuleName = module.name irModuleName = module.name
repositries = "$workingDir${File.pathSeparator}$workingDir/version2"
} }
K2JSCompiler().exec(TestMessageCollector(), Services.EMPTY, args) K2JSCompiler().exec(TestMessageCollector(), Services.EMPTY, args)
} }
@@ -425,6 +425,22 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
} }
} }
} }
@DisplayName("JS IR implementation dependency")
@GradleTest
fun testJsIrImplementationDependency(gradleVersion: GradleVersion) {
project("kotlin-js-browser-project", gradleVersion) {
buildGradleKts.modify(::transformBuildScriptWithPluginsDsl)
build("assemble")
projectPath.resolve("app/src/main/kotlin/App.kt").modify {
it.replace("sheldon()", "best()")
}
buildAndFail("assemble")
}
}
} }
@JsGradlePluginTests @JsGradlePluginTests
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import org.jetbrains.kotlin.gradle.tasks.configuration.Kotlin2JsCompileConfig import org.jetbrains.kotlin.gradle.tasks.configuration.Kotlin2JsCompileConfig
import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinJsIrLinkConfig import org.jetbrains.kotlin.gradle.tasks.configuration.KotlinJsIrLinkConfig
import org.jetbrains.kotlin.gradle.utils.filesProvider
internal class KotlinJsIrSourceSetProcessor( internal class KotlinJsIrSourceSetProcessor(
tasksProvider: KotlinTasksProvider, tasksProvider: KotlinTasksProvider,
@@ -46,7 +47,7 @@ internal class KotlinJsIrSourceSetProcessor(
val configAction = KotlinJsIrLinkConfig(binary) val configAction = KotlinJsIrLinkConfig(binary)
configAction.configureTask { configAction.configureTask {
it.description = taskDescription it.description = taskDescription
it.libraries.from({ compilationInfo.compileDependencyFiles }) it.libraries.from(compilation.runtimeDependencyFiles)
} }
configAction.configureTask { task -> configAction.configureTask { task ->
task.modeProperty.set(binary.mode) task.modeProperty.set(binary.mode)
@@ -66,6 +66,8 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
internal val createTestCompilation: Boolean internal val createTestCompilation: Boolean
) : KotlinTargetConfigurator<KotlinTargetType> { ) : KotlinTargetConfigurator<KotlinTargetType> {
protected open val runtimeIncludesCompilationOutputs = true
protected open fun setupCompilationDependencyFiles(compilation: KotlinCompilation<KotlinCommonOptions>) { protected open fun setupCompilationDependencyFiles(compilation: KotlinCompilation<KotlinCommonOptions>) {
val project = compilation.target.project val project = compilation.target.project
@@ -87,7 +89,7 @@ abstract class AbstractKotlinTargetConfigurator<KotlinTargetType : KotlinTarget>
target.compilations.create(KotlinCompilation.TEST_COMPILATION_NAME).apply { target.compilations.create(KotlinCompilation.TEST_COMPILATION_NAME).apply {
associateWith(main) associateWith(main)
if (this is KotlinCompilationToRunnableFiles) { if (runtimeIncludesCompilationOutputs && this is KotlinCompilationToRunnableFiles) {
// TODO: fix inconsistency? KT-27272 // TODO: fix inconsistency? KT-27272
runtimeDependencyFiles += project.files(output.allOutputs) runtimeDependencyFiles += project.files(output.allOutputs)
} }
@@ -23,6 +23,8 @@ open class KotlinJsIrTargetConfigurator() :
KotlinOnlyTargetConfigurator<KotlinJsIrCompilation, KotlinJsIrTarget>(true), KotlinOnlyTargetConfigurator<KotlinJsIrCompilation, KotlinJsIrTarget>(true),
KotlinTargetWithTestsConfigurator<KotlinJsReportAggregatingTestRun, KotlinJsIrTarget> { KotlinTargetWithTestsConfigurator<KotlinJsReportAggregatingTestRun, KotlinJsIrTarget> {
override val runtimeIncludesCompilationOutputs: Boolean = false
override val testRunClass: Class<KotlinJsReportAggregatingTestRun> get() = KotlinJsReportAggregatingTestRun::class.java override val testRunClass: Class<KotlinJsReportAggregatingTestRun> get() = KotlinJsReportAggregatingTestRun::class.java
override val archiveType: String override val archiveType: String
@@ -104,7 +106,6 @@ open class KotlinJsIrTargetConfigurator() :
override fun defineConfigurationsForTarget(target: KotlinJsIrTarget) { override fun defineConfigurationsForTarget(target: KotlinJsIrTarget) {
super.defineConfigurationsForTarget(target) super.defineConfigurationsForTarget(target)
implementationToApiElements(target)
if (target.isMpp!!) return if (target.isMpp!!) return