diff --git a/compiler/util-io/src/org/jetbrains/kotlin/konan/file/File.kt b/compiler/util-io/src/org/jetbrains/kotlin/konan/file/File.kt index 3e1845dc4bd..2bb6fdc12b2 100644 --- a/compiler/util-io/src/org/jetbrains/kotlin/konan/file/File.kt +++ b/compiler/util-io/src/org/jetbrains/kotlin/konan/file/File.kt @@ -19,6 +19,7 @@ import java.nio.file.attribute.BasicFileAttributes data class File constructor(internal val javaPath: Path) { constructor(parent: Path, child: String): this(parent.resolve(child)) constructor(parent: File, child: String): this(parent.javaPath.resolve(child)) + constructor(parent: File, child: File): this(parent.javaPath.resolve(child.javaPath)) constructor(path: String): this(Paths.get(path)) constructor(parent: String, child: String): this(Paths.get(parent, child)) 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 69f48beaa13..244afda4296 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/SearchPathResolver.kt @@ -5,6 +5,8 @@ import org.jetbrains.kotlin.konan.file.File import org.jetbrains.kotlin.library.impl.createKotlinLibraryComponents import org.jetbrains.kotlin.library.impl.isPre_1_4_Library import org.jetbrains.kotlin.util.* +import java.nio.file.InvalidPathException +import java.nio.file.Paths const val KOTLIN_STDLIB_NAME = "stdlib" @@ -69,29 +71,54 @@ abstract class KotlinLibrarySearchPathResolver( } } + /** + * Returns a [File] instance if the [path] is valid on the current file system and null otherwise. + * Doesn't check whether the file denoted by [path] really exists. + */ + private fun validFileOrNull(path: String): File? = + try { + File(Paths.get(path)) + } catch (_: InvalidPathException) { + null + } + + /** + * Returns a sequence of libraries passed to the compiler directly for which unique_name == [givenName]. + */ + private fun directLibsSequence(givenName: String): Sequence { + // Search among user-provided libraries by unique name. + // It's a workaround for maven publication. When a library is published without Gradle metadata, + // it has a complex file name (e.g. foo-macos_x64-1.0.klib). But a dependency on this lib in manifests + // of other libs uses its unique name written in the manifest (i.e just 'foo'). So we cannot resolve this + // library by its filename. But we have this library's file (we've downloaded it using maven dependency + // resolution) so we can pass it to the compiler directly. This code takes this into account and looks for + // a library dependencies also in libs passed to the compiler as files (passed to the resolver as the + // 'directLibraries' property). + return directLibraries.asSequence().filter { + it.uniqueName == givenName + }.map { + it.libraryFile + } + } + override fun resolutionSequence(givenPath: String): Sequence { - val given = File(givenPath) - val sequence = if (given.isAbsolute) { - sequenceOf(found(given)) - } else { - // Search among user-provided libraries by unique name. - // It's a workaround for maven publication. When a library is published without Gradle metadata, - // it has a complex file name (e.g. foo-macos_x64-1.0.klib). But a dependency on this lib in manifests - // of other libs uses its unique name written in the manifest (i.e just 'foo'). So we cannot resolve this - // library by its filename. But we have this library's file (we've downloaded it using maven dependency - // resolution) so we can pass it to the compiler directly. This code takes this into account and looks for - // a library dependencies also in libs passed to the compiler as files (passed to the resolver as the - // 'directLibraries' property). - val directLibs = directLibraries.asSequence().filter { - it.uniqueName == givenPath - }.map { - it.libraryFile + val given = validFileOrNull(givenPath) + val sequence = when { + given == null -> { + // The given path can't denote a real file, so just look for such + // unique_name among libraries passed to the compiler directly. + directLibsSequence(givenPath) } - // Search among libraries in repositoreis by library filename. - val repoLibs = searchRoots.asSequence().map { - found(File(it, givenPath)) + given.isAbsolute -> + sequenceOf(found(given)) + else -> { + // Search among libraries in repositories by library filename. + val repoLibs = searchRoots.asSequence().map { + found(File(it, given)) + } + // The given path still may denote a unique name of a direct library. + directLibsSequence(givenPath) + repoLibs } - directLibs + repoLibs } return sequence.filterNotNull() }