MPP: implement IdePlatformKind, its resolution and tooling for K/N
This commit is contained in:
committed by
Mikhail Glukhikh
parent
b86afb0bab
commit
7623169130
@@ -5,16 +5,14 @@ plugins {
|
||||
dependencies {
|
||||
compile(project(":idea"))
|
||||
compile(project(":idea:idea-core"))
|
||||
compile(project(":idea:idea-jvm"))
|
||||
compile(project(":compiler:frontend"))
|
||||
compileOnly(intellijDep())
|
||||
compile(project(":konan:konan-serializer"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" {
|
||||
projectDefault()
|
||||
// java.srcDirs("$rootDir/core/runtime.jvm/src")
|
||||
}
|
||||
"main" { projectDefault() }
|
||||
"test" { none() }
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
/**
|
||||
* @author Alefas
|
||||
*/
|
||||
class KonanAnalyzerFacade : ResolverForModuleFactory() {
|
||||
object KonanAnalyzerFacade : ResolverForModuleFactory() {
|
||||
override val targetPlatform: TargetPlatform
|
||||
get() = KonanPlatform
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@ class KonanDescriptorManager : ApplicationComponent {
|
||||
|
||||
companion object {
|
||||
|
||||
private const val currentAbiVersion = 1
|
||||
|
||||
@JvmStatic
|
||||
fun getInstance(): KonanDescriptorManager = ApplicationManager.getApplication().getComponent(KonanDescriptorManager::class.java)
|
||||
}
|
||||
|
||||
@@ -9,25 +9,22 @@ import com.intellij.util.indexing.FileBasedIndex
|
||||
import org.jetbrains.kotlin.idea.vfilefinder.KotlinFileIndexBase
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
class KonanMetaFileIndex
|
||||
: KotlinFileIndexBase<KonanMetaFileIndex>(KonanMetaFileIndex::class.java) {
|
||||
object KonanMetaFileIndex : KotlinFileIndexBase<KonanMetaFileIndex>(KonanMetaFileIndex::class.java) {
|
||||
|
||||
companion object {
|
||||
private const val VERSION = 4
|
||||
}
|
||||
override fun getIndexer() = INDEXER
|
||||
|
||||
/*todo: check version?!*/
|
||||
private val dataIndexer = indexer { fileContent ->
|
||||
val fragment = KonanDescriptorManager.getInstance().getCachedPackageFragment(fileContent.file)
|
||||
FqName(fragment.fqName)
|
||||
}
|
||||
override fun getInputFilter() = FileBasedIndex.InputFilter { it.fileType === KonanMetaFileType }
|
||||
|
||||
override fun getVersion() = VERSION
|
||||
|
||||
// this is to express intention to index all Kotlin/Native metadata files irrespectively to file size
|
||||
override fun getFileTypesWithSizeLimitNotApplicable() = listOf(KonanMetaFileType)
|
||||
|
||||
override fun getInputFilter() = FileBasedIndex.InputFilter { it.fileType === KonanMetaFileType }
|
||||
private const val VERSION = 4
|
||||
|
||||
override fun getIndexer() = dataIndexer
|
||||
|
||||
override fun getVersion() = VERSION
|
||||
/*todo: check version?!*/
|
||||
private val INDEXER = indexer { fileContent ->
|
||||
val fragment = KonanDescriptorManager.getInstance().getCachedPackageFragment(fileContent.file)
|
||||
FqName(fragment.fqName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collection;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public interface KonanModelProvider {
|
||||
@@ -21,11 +20,6 @@ public interface KonanModelProvider {
|
||||
|
||||
ExtensionPointName<KonanModelProvider> EP_NAME = ExtensionPointName.create("org.jetbrains.kotlin.native.konanModelProvider");
|
||||
|
||||
@NotNull
|
||||
Collection<KonanArtifact> getArtifacts(@NotNull Project project);
|
||||
|
||||
@Nullable
|
||||
Path getKonanHome(@NotNull Project project);
|
||||
|
||||
boolean reloadLibraries(@NotNull Project project, @NotNull Collection<Path> libraryPaths);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ open class KonanPaths(protected val project: Project) : ProjectComponent {
|
||||
|
||||
open fun konanDist(): Path? {
|
||||
for (provider in KonanModelProvider.EP_NAME.extensions) {
|
||||
provider.getKonanHome(project)?.let { return it }
|
||||
provider.getKonanHome(project)?.existing()?.let { return it }
|
||||
}
|
||||
return bundledKonanDist()
|
||||
}
|
||||
@@ -41,7 +41,7 @@ open class KonanPaths(protected val project: Project) : ProjectComponent {
|
||||
|
||||
val resolvedTargetName = HostManager.resolveAlias(target().name)
|
||||
val klibPath =
|
||||
konanDist()?.resolve(konanSpecificPlatformLibrariesPath(resolvedTargetName))?.takeIf { it.exists() } ?: return emptyList()
|
||||
konanDist()?.resolve(konanSpecificPlatformLibrariesPath(resolvedTargetName))?.existing() ?: return emptyList()
|
||||
|
||||
return Files.walk(klibPath, 1).filter {
|
||||
it.isDirectory() && it.fileName.toString() != KONAN_STDLIB_NAME && it != klibPath
|
||||
@@ -51,3 +51,5 @@ open class KonanPaths(protected val project: Project) : ProjectComponent {
|
||||
//todo: this is wrong, we are not allowing multiple targets in project
|
||||
open fun target(): KonanTarget = HostManager.host
|
||||
}
|
||||
|
||||
private fun Path.existing(): Path? = takeIf { exists() }
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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 com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.libraries.DummyLibraryProperties
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.LibraryType
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.konan.analyser.index.KonanMetaFileIndex
|
||||
import org.jetbrains.kotlin.idea.configuration.KotlinWithLibraryConfigurator
|
||||
import org.jetbrains.kotlin.idea.configuration.LibraryKindSearchScope
|
||||
import org.jetbrains.kotlin.idea.configuration.hasKotlinFilesOnlyInTests
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.idea.util.runWithAlternativeResolveEnabled
|
||||
import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor
|
||||
import org.jetbrains.kotlin.idea.vfilefinder.hasSomethingInPackage
|
||||
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
|
||||
|
||||
open class KonanModuleConfigurator : KotlinWithLibraryConfigurator() {
|
||||
|
||||
override val name: String get() = NAME
|
||||
|
||||
override val targetPlatform get() = KonanPlatform
|
||||
|
||||
override val presentableText get() = PRESENTABLE_TEXT
|
||||
|
||||
override fun isConfigured(module: Module) = hasKonanRuntimeInScope(module)
|
||||
|
||||
override val libraryName get() = KonanStandardLibraryDescription.LIBRARY_NAME
|
||||
|
||||
override val dialogTitle get() = KonanStandardLibraryDescription.DIALOG_TITLE
|
||||
|
||||
override val libraryCaption get() = KonanStandardLibraryDescription.LIBRARY_CAPTION
|
||||
|
||||
override val messageForOverrideDialog get() = KonanStandardLibraryDescription.KONAN_LIBRARY_CREATION
|
||||
|
||||
override fun getLibraryJarDescriptors(sdk: Sdk?) = emptyList<LibraryJarDescriptor>()
|
||||
|
||||
override val libraryMatcher: (Library, Project) -> Boolean = { library, _ ->
|
||||
library.getFiles(OrderRootType.CLASSES).firstOrNull { it.nameWithoutExtension == KONAN_STDLIB_NAME } != null
|
||||
}
|
||||
|
||||
override val libraryType: LibraryType<DummyLibraryProperties>? get() = null
|
||||
|
||||
companion object {
|
||||
const val NAME = "Konan"
|
||||
const val PRESENTABLE_TEXT = "Native"
|
||||
}
|
||||
}
|
||||
|
||||
fun hasKonanRuntimeInScope(module: Module): Boolean {
|
||||
return runReadAction {
|
||||
val scope = module.getModuleWithDependenciesAndLibrariesScope(hasKotlinFilesOnlyInTests(module))
|
||||
hasKonanMetadataFile(module.project, LibraryKindSearchScope(module, scope, KonanLibraryKind))
|
||||
}
|
||||
}
|
||||
|
||||
private val KONAN_FQ_NAME = FqName("kotlin.native")
|
||||
|
||||
fun hasKonanMetadataFile(project: Project, scope: GlobalSearchScope): Boolean {
|
||||
return runReadAction {
|
||||
project.runWithAlternativeResolveEnabled {
|
||||
KonanMetaFileIndex.hasSomethingInPackage(KONAN_FQ_NAME, scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.konan.K2NativeCompilerArguments
|
||||
import org.jetbrains.kotlin.config.TargetPlatformVersion
|
||||
import org.jetbrains.kotlin.platform.IdePlatform
|
||||
import org.jetbrains.kotlin.platform.IdePlatformKind
|
||||
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
|
||||
|
||||
object KonanPlatformKind : IdePlatformKind<KonanPlatformKind>() {
|
||||
|
||||
override fun platformByCompilerArguments(arguments: CommonCompilerArguments): IdePlatform<KonanPlatformKind, CommonCompilerArguments>? {
|
||||
return if (arguments is K2NativeCompilerArguments) Platform
|
||||
else null
|
||||
}
|
||||
|
||||
override val compilerPlatform get() = KonanPlatform
|
||||
|
||||
override val platforms get() = listOf(Platform)
|
||||
override val defaultPlatform get() = Platform
|
||||
|
||||
override val argumentsClass get() = K2NativeCompilerArguments::class.java
|
||||
|
||||
override val name get() = "Native"
|
||||
|
||||
object Platform : IdePlatform<KonanPlatformKind, K2NativeCompilerArguments>() {
|
||||
override val kind get() = KonanPlatformKind
|
||||
override val version get() = TargetPlatformVersion.NoVersion
|
||||
override fun createArguments(init: K2NativeCompilerArguments.() -> Unit) = K2NativeCompilerArguments().apply(init)
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean = other === KonanPlatformKind
|
||||
override fun hashCode(): Int = javaClass.hashCode()
|
||||
}
|
||||
|
||||
val IdePlatformKind<*>?.isKonan
|
||||
get() = this === KonanPlatformKind
|
||||
|
||||
val IdePlatform<*, *>?.isKonan
|
||||
get() = this === KonanPlatformKind.Platform
|
||||
+21
-21
@@ -3,50 +3,50 @@
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.konan.analyser
|
||||
package org.jetbrains.kotlin.ide.konan
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.ProjectManager
|
||||
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.analyzer.ResolverForModuleFactory
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.caches.resolve.IdePlatformSupport
|
||||
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.resolve.PlatformAnalysisSettings
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.konan.library.createKonanLibrary
|
||||
import org.jetbrains.kotlin.konan.utils.KonanFactories.DefaultDeserializedDescriptorFactory
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform
|
||||
|
||||
/**
|
||||
* @author Alefas
|
||||
*/
|
||||
class KonanPlatformSupport : IdePlatformSupport() {
|
||||
class KonanPlatformKindResolution : IdePlatformKindResolution {
|
||||
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
|
||||
return virtualFile.extension == "klib"
|
||||
|| virtualFile.isDirectory && virtualFile.children.any { it.name == "manifest" }
|
||||
}
|
||||
|
||||
override val resolverForModuleFactory: ResolverForModuleFactory
|
||||
get() = KonanAnalyzerFacade()
|
||||
override val libraryKind: PersistentLibraryKind<*>?
|
||||
get() = KonanLibraryKind
|
||||
|
||||
override val libraryKind: PersistentLibraryKind<*>? = null
|
||||
override val kind get() = KonanPlatformKind
|
||||
|
||||
override val platform: TargetPlatform
|
||||
get() = KonanPlatform
|
||||
override val resolverForModuleFactory get() = KonanAnalyzerFacade
|
||||
|
||||
override fun createBuiltIns(settings: PlatformAnalysisSettings, sdkContext: GlobalContextImpl) = createKonanBuiltIns(sdkContext)
|
||||
|
||||
override fun isModuleForPlatform(module: Module) = true
|
||||
override fun createBuiltIns(settings: PlatformAnalysisSettings, projectContext: ProjectContext) =
|
||||
createKonanBuiltIns(projectContext)
|
||||
}
|
||||
|
||||
private fun createKonanBuiltIns(sdkContext: GlobalContextImpl): KotlinBuiltIns {
|
||||
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 {
|
||||
KonanPaths.getInstance(it).konanStdlib()?.takeIf { it.exists() }
|
||||
val stdlibPath = ProjectManager.getInstance().openProjects.asSequence().mapNotNull { project ->
|
||||
KonanPaths.getInstance(project).konanStdlib()?.takeIf { it.exists() }
|
||||
}.firstOrNull()
|
||||
|
||||
if (stdlibPath != null) {
|
||||
@@ -55,7 +55,7 @@ private fun createKonanBuiltIns(sdkContext: GlobalContextImpl): KotlinBuiltIns {
|
||||
val builtInsModule = DefaultDeserializedDescriptorFactory.createDescriptorAndNewBuiltIns(
|
||||
library,
|
||||
LanguageVersionSettingsImpl.DEFAULT,
|
||||
sdkContext.storageManager
|
||||
projectContext.storageManager
|
||||
)
|
||||
builtInsModule.setDependencies(listOf(builtInsModule))
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.libraries.DummyLibraryProperties
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
|
||||
import org.jetbrains.konan.analyser.KonanAnalyzerFacade
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.gradle.KotlinPlatform
|
||||
import org.jetbrains.kotlin.idea.framework.CustomLibraryDescriptorWithDeferredConfig
|
||||
import org.jetbrains.kotlin.idea.framework.KotlinLibraryKind
|
||||
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import javax.swing.Icon
|
||||
|
||||
class KonanPlatformKindTooling : IdePlatformKindTooling() {
|
||||
|
||||
override val kind = KonanPlatformKind
|
||||
|
||||
override fun compilerArgumentsForProject(project: Project): CommonCompilerArguments? = null
|
||||
|
||||
override val resolverForModuleFactory get() = KonanAnalyzerFacade
|
||||
|
||||
override val mavenLibraryIds: List<String> get() = emptyList()
|
||||
override val gradlePluginId: String get() = ""
|
||||
override val gradlePlatformIds: List<KotlinPlatform> get() = listOf(KotlinPlatform.KONAN)
|
||||
|
||||
override val libraryKind: PersistentLibraryKind<*> = KonanLibraryKind
|
||||
override fun getLibraryDescription(project: Project) = KonanStandardLibraryDescription(project)
|
||||
override fun getLibraryVersionProvider(project: Project): (Library) -> String? = { null }
|
||||
|
||||
override fun getTestIcon(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor): Icon? = null
|
||||
|
||||
override fun acceptsAsEntryPoint(function: KtFunction) = true
|
||||
}
|
||||
|
||||
object KonanLibraryKind : PersistentLibraryKind<DummyLibraryProperties>("kotlin.native"), KotlinLibraryKind {
|
||||
override val compilerPlatform: TargetPlatform
|
||||
get() = KonanPlatformKind.compilerPlatform
|
||||
|
||||
override fun createDefaultProperties() = DummyLibraryProperties.INSTANCE!!
|
||||
}
|
||||
|
||||
class KonanStandardLibraryDescription(project: Project?) :
|
||||
CustomLibraryDescriptorWithDeferredConfig(
|
||||
project,
|
||||
KonanModuleConfigurator.NAME,
|
||||
LIBRARY_NAME,
|
||||
DIALOG_TITLE,
|
||||
LIBRARY_CAPTION,
|
||||
KonanLibraryKind,
|
||||
SUITABLE_LIBRARY_KINDS
|
||||
) {
|
||||
|
||||
companion object {
|
||||
val LIBRARY_NAME = "KotlinNative"
|
||||
|
||||
val KONAN_LIBRARY_CREATION = "Native Library Creation"
|
||||
val DIALOG_TITLE = "Create Kotlin Native Library"
|
||||
val LIBRARY_CAPTION = "Kotlin Native Library"
|
||||
val SUITABLE_LIBRARY_KINDS = setOf(KonanLibraryKind)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user