K/N: Refactor KotlinNativePluginSearchPathResolver
Get rid of dependency on KonanPaths project component
This commit is contained in:
committed by
Mikhail Glukhikh
parent
b157e9d5a1
commit
dd203830a8
@@ -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
|
||||
|
||||
+72
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user