From 22ea5c7de4962f393b5b91aaf88b76c12c94769c Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Thu, 15 Apr 2021 13:23:59 +0200 Subject: [PATCH] Demote fatal error to warning on unresolved libraries mentioned in Klib's manifest 'depends' for metadata compilation ^KT-46107 --- .../impl/KotlinLibraryResolverImpl.kt | 15 ++++--- .../jetbrains/kotlin/library/KotlinLibrary.kt | 9 ++-- .../kotlin/library/SearchPathResolver.kt | 45 +++++++++++++------ .../kotlin/library/UnresolvedLibrary.kt | 35 ++++++++++++--- .../kotlin/backend/konan/KonanConfig.kt | 8 ++-- .../konan/KonanLibrariesResolveSupport.kt | 9 ++-- 6 files changed, 84 insertions(+), 37 deletions(-) diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/resolver/impl/KotlinLibraryResolverImpl.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/resolver/impl/KotlinLibraryResolverImpl.kt index 53fb52f6aff..9969f8e9316 100644 --- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/resolver/impl/KotlinLibraryResolverImpl.kt +++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/resolver/impl/KotlinLibraryResolverImpl.kt @@ -25,11 +25,12 @@ import org.jetbrains.kotlin.library.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.library.resolver.LibraryOrder import org.jetbrains.kotlin.util.WithLogger -fun SearchPathResolver.libraryResolver() - = KotlinLibraryResolverImpl(this) +fun SearchPathResolver.libraryResolver(resolveManifestDependenciesLenient: Boolean = false) + = KotlinLibraryResolverImpl(this, resolveManifestDependenciesLenient) -class KotlinLibraryResolverImpl( - override val searchPathResolver: SearchPathResolver +class KotlinLibraryResolverImpl internal constructor( + override val searchPathResolver: SearchPathResolver, + val resolveManifestDependenciesLenient: Boolean ): KotlinLibraryResolver, WithLogger by searchPathResolver { override fun resolveWithDependencies( @@ -56,7 +57,7 @@ class KotlinLibraryResolverImpl( ): List { val userProvidedLibraries = unresolvedLibraries.asSequence() - .map { searchPathResolver.resolve(it) } + .mapNotNull { searchPathResolver.resolve(it) } .toList() val defaultLibraries = searchPathResolver.defaultLinks(noStdLib, noDefaultLibs, noEndorsedLibs) @@ -115,10 +116,10 @@ class KotlinLibraryResolverImpl( var newDependencies = rootLibraries do { newDependencies = newDependencies.map { library: KotlinResolvedLibraryImpl -> - library.library.unresolvedDependencies.asSequence() + library.library.unresolvedDependencies(resolveManifestDependenciesLenient).asSequence() .filterNot { searchPathResolver.isProvidedByDefault(it) } - .map { KotlinResolvedLibraryImpl(searchPathResolver.resolve(it)) } + .mapNotNull { KotlinResolvedLibraryImpl(searchPathResolver.resolve(it) ?: return@mapNotNull null) } .map { resolved -> val absoluteFile = resolved.library.libraryFile.absoluteFile if (absoluteFile in cache) { diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt index 4dccb4543c4..a9a7468f52d 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt @@ -74,9 +74,12 @@ val BaseKotlinLibrary.uniqueName: String val BaseKotlinLibrary.shortName: String? get() = manifestProperties.getProperty(KLIB_PROPERTY_SHORT_NAME) -val BaseKotlinLibrary.unresolvedDependencies: List - get() = manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true) - .map { UnresolvedLibrary(it, manifestProperties.getProperty("dependency_version_$it")) } +val BaseKotlinLibrary.unresolvedDependencies: List + get() = unresolvedDependencies(lenient = false).map { it as RequiredUnresolvedLibrary } + +fun BaseKotlinLibrary.unresolvedDependencies(lenient: Boolean = false): List = + manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS, escapeInQuotes = true) + .map { UnresolvedLibrary(it, manifestProperties.getProperty("dependency_version_$it"), lenient = lenient) } interface KotlinLibrary : BaseKotlinLibrary, MetadataLibrary, IrLibrary diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt index 08014e13cab..b7834d49e63 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt @@ -16,13 +16,19 @@ const val KOTLIN_STDLIB_NAME = "stdlib" interface SearchPathResolver : WithLogger { val searchRoots: List fun resolutionSequence(givenPath: String): Sequence - fun resolve(unresolved: UnresolvedLibrary, isDefaultLink: Boolean = false): L + fun resolve(unresolved: LenientUnresolvedLibrary, isDefaultLink: Boolean = false): L? + fun resolve(unresolved: RequiredUnresolvedLibrary, isDefaultLink: Boolean = false): L fun resolve(givenPath: String): L fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean, noEndorsedLibs: Boolean): List fun libraryMatch(candidate: L, unresolved: UnresolvedLibrary): Boolean fun isProvidedByDefault(unresolved: UnresolvedLibrary): Boolean = false } +fun SearchPathResolver.resolve(unresolved: UnresolvedLibrary): L? = when (unresolved) { + is LenientUnresolvedLibrary -> resolve(unresolved) + is RequiredUnresolvedLibrary -> resolve(unresolved) +} + // This is a simple library resolver that only cares for file names. abstract class KotlinLibrarySearchPathResolver( repositories: List, @@ -134,29 +140,42 @@ abstract class KotlinLibrarySearchPathResolver( // Default libraries could be resolved several times during findLibraries and resolveDependencies. // Store already resolved libraries. - private val resolvedLibraries = HashMap() + private inner class ResolvedLibrary(val library: L?) - override fun resolve(unresolved: UnresolvedLibrary, isDefaultLink: Boolean): L { + private val resolvedLibraries = HashMap() + + private fun resolveOrNull(unresolved: UnresolvedLibrary, isDefaultLink: Boolean): L? { return resolvedLibraries.getOrPut(unresolved) { val givenPath = unresolved.path try { - val fileSequence = resolutionSequence(givenPath) - val matching = fileSequence - .filterOutPre_1_4_libraries() - .flatMap { libraryComponentBuilder(it, isDefaultLink).asSequence() } - .map { it.takeIf { libraryMatch(it, unresolved) } } - .filterNotNull() - - matching.firstOrNull() ?: run { - logger.fatal("Could not find \"$givenPath\" in ${searchRoots.map { it.absolutePath }}") - } + resolutionSequence(givenPath) + .filterOutPre_1_4_libraries() + .flatMap { libraryComponentBuilder(it, isDefaultLink).asSequence() } + .map { it.takeIf { libraryMatch(it, unresolved) } } + .filterNotNull() + .firstOrNull() + .let(::ResolvedLibrary) } catch (e: Throwable) { logger.error("Failed to resolve Kotlin library: $givenPath") throw e } + }.library + } + + override fun resolve(unresolved: LenientUnresolvedLibrary, isDefaultLink: Boolean): L? { + return resolveOrNull(unresolved, isDefaultLink).also { resolvedLibrary -> + if (resolvedLibrary == null) { + logger.warning("Could not find \"${unresolved.path}\" in ${searchRoots.map { it.absolutePath }}") + } } } + override fun resolve(unresolved: RequiredUnresolvedLibrary, isDefaultLink: Boolean): L { + return resolveOrNull(unresolved, isDefaultLink) + ?: logger.fatal("Could not find \"${unresolved.path}\" in ${searchRoots.map { it.absolutePath }}") + + } + override fun libraryMatch(candidate: L, unresolved: UnresolvedLibrary): Boolean = true override fun resolve(givenPath: String) = resolve(UnresolvedLibrary(givenPath, null), false) diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/UnresolvedLibrary.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/UnresolvedLibrary.kt index f24067f26cc..9917fefd105 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/UnresolvedLibrary.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/UnresolvedLibrary.kt @@ -1,10 +1,33 @@ +@file:Suppress("FunctionName") + package org.jetbrains.kotlin.library -data class UnresolvedLibrary( - val path: String, - val libraryVersion: String?) { +fun UnresolvedLibrary(path: String, libraryVersion: String?): RequiredUnresolvedLibrary = + RequiredUnresolvedLibrary(path, libraryVersion) - fun substitutePath(newPath: String): UnresolvedLibrary { - return UnresolvedLibrary(newPath, libraryVersion) +fun UnresolvedLibrary(path: String, libraryVersion: String?, lenient: Boolean): UnresolvedLibrary = + if (lenient) LenientUnresolvedLibrary(path, libraryVersion) else RequiredUnresolvedLibrary(path, libraryVersion) + +sealed class UnresolvedLibrary { + abstract val path: String + abstract val libraryVersion: String? + abstract fun substitutePath(newPath: String): UnresolvedLibrary +} + +data class RequiredUnresolvedLibrary( + override val path: String, + override val libraryVersion: String? +) : UnresolvedLibrary() { + override fun substitutePath(newPath: String): RequiredUnresolvedLibrary { + return copy(path = newPath) } -} \ No newline at end of file +} + +data class LenientUnresolvedLibrary( + override val path: String, + override val libraryVersion: String? +) : UnresolvedLibrary() { + override fun substitutePath(newPath: String): LenientUnresolvedLibrary { + return copy(path = newPath) + } +} diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt index 512424bd308..abbb17440cb 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt @@ -81,7 +81,9 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration internal val purgeUserLibs: Boolean get() = configuration.getBoolean(KonanConfigKeys.PURGE_USER_LIBS) - internal val resolve = KonanLibrariesResolveSupport(configuration, target, distribution) + internal val resolve = KonanLibrariesResolveSupport( + configuration, target, distribution, resolveManifestDependenciesLenient = metadataKlib + ) internal val resolvedLibraries get() = resolve.resolvedLibraries @@ -186,7 +188,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration internal val nativeLibraries: List = configuration.getList(KonanConfigKeys.NATIVE_LIBRARY_FILES) - internal val includeBinaries: List = + internal val includeBinaries: List = configuration.getList(KonanConfigKeys.INCLUDED_BINARY_FILES) internal val languageVersionSettings = @@ -202,5 +204,5 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration internal val isInteropStubs: Boolean get() = manifestProperties?.getProperty("interop") == "true" } -fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String) +fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String) = this.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(priority, message) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLibrariesResolveSupport.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLibrariesResolveSupport.kt index 6bc89469667..75dee4ddb17 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLibrariesResolveSupport.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLibrariesResolveSupport.kt @@ -8,10 +8,8 @@ package org.jetbrains.kotlin.backend.konan import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.konan.CompilerVersion import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.konan.library.defaultResolver -import org.jetbrains.kotlin.konan.parseCompilerVersion import org.jetbrains.kotlin.konan.target.Distribution import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.library.UnresolvedLibrary @@ -22,7 +20,8 @@ import org.jetbrains.kotlin.util.Logger class KonanLibrariesResolveSupport( configuration: CompilerConfiguration, target: KonanTarget, - distribution: Distribution + distribution: Distribution, + resolveManifestDependenciesLenient: Boolean ) { private val includedLibraryFiles = configuration.getList(KonanConfigKeys.INCLUDED_LIBRARIES).map { File(it) } @@ -56,7 +55,7 @@ class KonanLibrariesResolveSupport( target, distribution, resolverLogger - ).libraryResolver() + ).libraryResolver(resolveManifestDependenciesLenient) // We pass included libraries by absolute paths to avoid repository-based resolution for them. // Strictly speaking such "direct" libraries should be specially handled by the resolver, not by KonanConfig. @@ -80,4 +79,4 @@ class KonanLibrariesResolveSupport( internal val includedLibraries = getIncludedLibraries(includedLibraryFiles, configuration, resolvedLibraries) -} \ No newline at end of file +}