MPP: Keep original capabilities in descriptors created for all KLIBs

This commit is contained in:
Dmitriy Dolovov
2018-09-03 16:50:49 +03:00
committed by Mikhail Glukhikh
parent 7623169130
commit beb12b693f
3 changed files with 51 additions and 19 deletions
@@ -25,13 +25,13 @@ import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.libraryResolver
import org.jetbrains.kotlin.konan.utils.KonanFactories
import org.jetbrains.kotlin.konan.utils.KonanFactories.DefaultResolvedDescriptorsFactory
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
import org.jetbrains.kotlin.serialization.konan.KonanResolvedModuleDescriptors
import org.jetbrains.kotlin.storage.StorageManager
import java.io.File.pathSeparatorChar
import java.io.File.separatorChar
const val KONAN_CURRENT_ABI_VERSION = 1
@@ -67,6 +67,7 @@ fun Module.createResolvedModuleDescriptors(
languageVersionSettings: LanguageVersionSettings
): KonanResolvedModuleDescriptors {
// This is to preserve "capabilities" from the original IntelliJ LibraryInfo:
val libraryMap = mutableMapOf<String, LibraryInfo>()
ModuleRootManager.getInstance(this).orderEntries().forEachLibrary { intellijLibrary ->
intellijLibrary.name?.let { name -> libraryMap[name] = LibraryInfo(project, intellijLibrary) }
@@ -76,16 +77,15 @@ fun Module.createResolvedModuleDescriptors(
val resolvedLibraries =
KonanPluginSearchPathResolver(project).libraryResolver(KONAN_CURRENT_ABI_VERSION).resolveWithDependencies(libraryMap.keys.toList())
return KonanFactories.DefaultResolvedDescriptorsFactory.createResolved(
return DefaultResolvedDescriptorsFactory.createResolved(
resolvedLibraries,
storageManager,
builtIns,
languageVersionSettings,
null,
// Preserve capabilities from the original IntelliJ library:
{ konanLibrary -> libraryMap[konanLibrary.pureName]?.capabilities ?: emptyMap() }
)
null
// This is to preserve "capabilities" from the original IntelliJ LibraryInfo:
) { konanLibrary -> libraryMap[konanLibrary.pureName]?.capabilities ?: emptyMap() }
}
private val KonanLibrary.pureName
get() = libraryName.substringAfterLast(pathSeparatorChar)
get() = libraryName.substringAfterLast(separatorChar)
@@ -64,12 +64,15 @@ fun hasKonanRuntimeInScope(module: Module): Boolean {
}
}
private val KONAN_FQ_NAME = FqName("kotlin.native")
private val KONAN_FQ_NAMES = listOf(
"kotlin.native",
"konan.native" // Keep "konan.native" for backward compatibility with older versions of Kotlin/Native.
).map { FqName(it) }
fun hasKonanMetadataFile(project: Project, scope: GlobalSearchScope): Boolean {
return runReadAction {
project.runWithAlternativeResolveEnabled {
KonanMetaFileIndex.hasSomethingInPackage(KONAN_FQ_NAME, scope)
KONAN_FQ_NAMES.any { KonanMetaFileIndex.hasSomethingInPackage(it, scope) }
}
}
}
@@ -6,24 +6,28 @@
package org.jetbrains.kotlin.ide.konan
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.io.exists
import org.jetbrains.konan.KONAN_CURRENT_ABI_VERSION
import org.jetbrains.konan.analyser.KonanAnalyzerFacade
import org.jetbrains.konan.settings.KonanPaths
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution
import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.context.GlobalContextImpl
import org.jetbrains.kotlin.context.ProjectContext
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
import org.jetbrains.kotlin.idea.caches.resolve.PlatformAnalysisSettings
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
import org.jetbrains.kotlin.konan.library.createKonanLibrary
import org.jetbrains.kotlin.konan.utils.KonanFactories.DefaultDeserializedDescriptorFactory
import java.nio.file.Path
import java.nio.file.Paths
class KonanPlatformKindResolution : IdePlatformKindResolution {
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
@@ -42,20 +46,45 @@ class KonanPlatformKindResolution : IdePlatformKindResolution {
createKonanBuiltIns(projectContext)
}
val Module.isKonanModule: Boolean
get() {
val settings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this)
return settings.platform.isKonan
}
private fun createKonanBuiltIns(projectContext: ProjectContext): KotlinBuiltIns {
// TODO: it depends on a random project's stdlib, propagate the actual project here
val stdlibPath = ProjectManager.getInstance().openProjects.asSequence().mapNotNull { project ->
KonanPaths.getInstance(project).konanStdlib()?.takeIf { it.exists() }
}.firstOrNull()
// TODO: It depends on a random project's stdlib, propagate the actual project here.
val stdlib: Pair<Path, LibraryInfo>? = ProjectManager.getInstance().openProjects.asSequence().mapNotNull { project ->
if (stdlibPath != null) {
val library = createKonanLibrary(stdlibPath.File(), KONAN_CURRENT_ABI_VERSION)
ModuleManager.getInstance(project).modules.asSequence().filter { it.isKonanModule }.mapNotNull { module ->
var result: Pair<Path, LibraryInfo>? = null
ModuleRootManager.getInstance(module).orderEntries().forEachLibrary { library ->
if (library.name == KONAN_STDLIB_NAME) {
val libraryInfo = LibraryInfo(project, library)
val path = libraryInfo.getLibraryRoots().firstOrNull()?.let { Paths.get(it) }?.takeIf { it.exists() }
if (path != null) result = path to libraryInfo
}
result == null
}
result
}
}.flatten().firstOrNull()
if (stdlib != null) {
val (path, libraryInfo) = stdlib
val library = createKonanLibrary(path.File(), KONAN_CURRENT_ABI_VERSION)
val builtInsModule = DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(
library,
LanguageVersionSettingsImpl.DEFAULT,
projectContext.storageManager
projectContext.storageManager,
// This is to preserve "capabilities" from the original IntelliJ LibraryInfo:
customCapabilities = libraryInfo.capabilities
)
builtInsModule.setDependencies(listOf(builtInsModule))