K/N: Refactor KotlinNativePluginSearchPathResolver

Get rid of dependency on KonanPaths project component
This commit is contained in:
Dmitriy Dolovov
2018-09-07 12:05:53 +03:00
committed by Mikhail Glukhikh
parent b157e9d5a1
commit dd203830a8
8 changed files with 159 additions and 151 deletions
@@ -1,78 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.konan
import com.intellij.openapi.project.Project
import org.jetbrains.konan.settings.KonanPaths
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.target.KonanTarget
class KonanPluginSearchPathResolver(val project: Project) : SearchPathResolverWithTarget {
private val paths by lazy { KonanPaths(project) }
override val searchRoots: List<File> by lazy {
paths.konanDist()?.let { distPath ->
listOf(KONAN_COMMON_LIBS_PATH, konanSpecificPlatformLibrariesPath(target.toString())).mapNotNull { relativePath ->
distPath.resolve(relativePath).File().takeIf { it.exists }
}
} ?: emptyList()
}
override fun resolve(givenPath: String): File {
val given = File(givenPath)
if (given.isAbsolute) {
found(given)?.apply { return this }
} else {
searchRoots.forEach {
found(File(it, givenPath))?.apply { return this }
}
}
error("Could not find \"$givenPath\" in ${searchRoots.map { it.absolutePath }}.")
}
override fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean): List<File> {
val result = mutableListOf<File>()
if (!noStdLib) {
result.add(resolve(KONAN_STDLIB_NAME))
}
if (!noDefaultLibs) {
val defaultLibs = searchRoots.flatMap { it.listFiles }
.filterNot { it.name.removeSuffix(KLIB_FILE_EXTENSION_WITH_DOT) == KONAN_STDLIB_NAME }
.map { File(it.absolutePath) }
result.addAll(defaultLibs)
}
return result
}
override val target: KonanTarget
get() = paths.target()
private fun found(candidate: File): File? {
fun check(file: File): Boolean =
file.exists && (file.isFile || File(file, "manifest").exists)
val noSuffix = File(candidate.path.removeSuffix(KLIB_FILE_EXTENSION_WITH_DOT))
val withSuffix = File(candidate.path.suffixIfNot(KLIB_FILE_EXTENSION_WITH_DOT))
return when {
check(withSuffix) -> withSuffix
check(noSuffix) -> noSuffix
else -> null
}
}
}
private fun String.suffixIfNot(suffix: String) = if (this.endsWith(suffix)) this else "$this$suffix"
@@ -9,6 +9,7 @@ import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.fileTypes.FileTypeConsumer
import com.intellij.openapi.fileTypes.FileTypeFactory
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.konan.library.KLIB_METADATA_FILE_EXTENSION
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
@@ -40,7 +41,7 @@ class KonanMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
object KonanMetaFileType : FileType {
override fun getName() = "KNM"
override fun getDescription() = "Kotlin/Native Metadata"
override fun getDefaultExtension() = "knm"
override fun getDefaultExtension() = KLIB_METADATA_FILE_EXTENSION
override fun getIcon() = null
override fun isBinary() = true
override fun isReadOnly() = true
@@ -0,0 +1,72 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ide.konan
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.*
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.target.PredefinedKonanTargets
import java.nio.file.Path
import java.nio.file.Paths
internal class KotlinNativePluginSearchPathResolver(bundledLibraryPaths: Iterable<String>) : SearchPathResolverWithTarget {
override val target: KonanTarget
override val searchRoots: List<File>
init {
val commonLibsRoot = bundledLibraryPaths.firstParentPath { it.endsWith(KONAN_COMMON_LIBS_PATH) }
val platformLibsRoot = bundledLibraryPaths.firstParentPath { it.parent.endsWith(KONAN_ALL_PLATFORM_LIBS_PATH) }
val platformName = platformLibsRoot?.fileName?.toString()
target = if (platformName != null) {
PredefinedKonanTargets.getByName(platformName) ?: error("Unexpected Kotlin/Native target platform name: $platformName")
} else {
// If not possible to determine platform by platform libs root, then fallback to the host platform:
HostManager.host
}
searchRoots = listOfNotNull(commonLibsRoot, platformLibsRoot).map { File(it) }
}
override fun resolve(givenPath: String): File {
val given = File(givenPath)
if (given.isAbsolute) {
found(given)?.apply { return this }
} else {
searchRoots.forEach {
found(File(it, givenPath))?.apply { return this }
}
}
error("Could not find \"$givenPath\" in ${searchRoots.map { it.absolutePath }}.")
}
private fun found(candidate: File): File? {
fun checkAsFile(file: File): Boolean = file.isFile
fun checkAsDirectory(dir: File): Boolean =
dir.isDirectory && File(dir, "linkdata").listFilesOrEmpty.any { it.extension == KLIB_METADATA_FILE_EXTENSION }
val candidatePath = candidate.path
File(candidatePath.removeSuffix(KLIB_FILE_EXTENSION_WITH_DOT)).let { if (checkAsDirectory(it)) return it }
File(candidatePath.suffixIfNot(KLIB_FILE_EXTENSION_WITH_DOT)).let { if (checkAsFile(it)) return it }
return null
}
// For IDEA plugin all dependencies (KLIBs) should be explicitly provided by underlying layer (Gradle plugin).
// Therefore, no default libraries.
override fun defaultLinks(noStdLib: Boolean, noDefaultLibs: Boolean) = emptyList<File>()
}
private fun Iterable<String>.firstParentPath(predicate: (Path) -> Boolean) =
asSequence().mapNotNull { Paths.get(it).parent }.firstOrNull(predicate)
private fun String.suffixIfNot(suffix: String) = if (this.endsWith(suffix)) this else "$this$suffix"
@@ -12,7 +12,6 @@ import com.intellij.psi.SingleRootFileViewProvider
import com.intellij.psi.impl.PsiFileFactoryImpl
import com.intellij.psi.stubs.PsiFileStub
import com.intellij.testFramework.LightVirtualFile
import org.jetbrains.konan.KonanPluginSearchPathResolver
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -52,17 +51,19 @@ fun ModuleInfo.createResolvedModuleDescriptors(
val libraryMap =
this.dependencies().filterIsInstance<LibraryInfo>().flatMap { dependency ->
if (dependency.platform == KonanPlatform) {
dependency.getLibraryRoots().map { file ->
file to dependency
dependency.getLibraryRoots().map { libraryRoot ->
libraryRoot to dependency
}
} else {
emptyList()
}
}.toMap()
val resolvedLibraries =
KonanPluginSearchPathResolver(project).libraryResolver(KONAN_CURRENT_ABI_VERSION)
.resolveWithDependencies(libraryMap.keys.toList(), true, true)
val libraryPaths = libraryMap.keys.toList()
val resolvedLibraries = KotlinNativePluginSearchPathResolver(libraryPaths)
.libraryResolver(KONAN_CURRENT_ABI_VERSION)
.resolveWithDependencies(libraryPaths)
return DefaultResolvedDescriptorsFactory.createResolved(
resolvedLibraries,
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ide.konan
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.konan.analyser.index.KonanMetaFileType
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution
@@ -19,6 +18,7 @@ import org.jetbrains.kotlin.idea.caches.project.getModuleInfosFromIdeaModel
import org.jetbrains.kotlin.idea.caches.resolve.PlatformAnalysisSettings
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION
import org.jetbrains.kotlin.konan.library.KLIB_METADATA_FILE_EXTENSION
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
import org.jetbrains.kotlin.konan.library.createKonanLibrary
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultDeserializedDescriptorFactory
@@ -29,7 +29,7 @@ class NativePlatformKindResolution : IdePlatformKindResolution {
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
return if (virtualFile.isDirectory) {
virtualFile.findChild("linkdata")?.takeIf { it.isDirectory }
?.children?.any { it.extension == KonanMetaFileType.defaultExtension } == true
?.children?.any { it.extension == KLIB_METADATA_FILE_EXTENSION } == true
} else {
virtualFile.extension == KLIB_FILE_EXTENSION
}