diff --git a/.idea/dictionaries/dmitriy_dolovov.xml b/.idea/dictionaries/dmitriy_dolovov.xml new file mode 100644 index 00000000000..3af0fb03b93 --- /dev/null +++ b/.idea/dictionaries/dmitriy_dolovov.xml @@ -0,0 +1,7 @@ + + + + konan + + + \ No newline at end of file diff --git a/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/GradleKonanModelProvider.kt b/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/GradleKonanModelProvider.kt index 5a5cb6baa15..4f4c517d4b0 100644 --- a/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/GradleKonanModelProvider.kt +++ b/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/GradleKonanModelProvider.kt @@ -5,77 +5,10 @@ package org.jetbrains.konan.gradle -import com.intellij.openapi.externalSystem.model.ProjectKeys -import com.intellij.openapi.externalSystem.service.project.ProjectDataManager -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.find -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.findAll import com.intellij.openapi.project.Project -import com.intellij.openapi.util.Key -import com.intellij.util.BooleanFunction -import com.sun.media.jfxmediaimpl.platform.PlatformManager -import org.jetbrains.konan.settings.KonanArtifact import org.jetbrains.konan.settings.KonanModelProvider -import org.jetbrains.kotlin.gradle.plugin.model.KonanModel -import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifact -import org.jetbrains.kotlin.konan.target.PlatformManager -import org.jetbrains.kotlin.konan.target.customerDistribution -import org.jetbrains.plugins.gradle.settings.GradleSettings -import org.jetbrains.plugins.gradle.util.GradleConstants -import java.io.File import java.nio.file.Path class GradleKonanModelProvider : KonanModelProvider { - override fun reloadLibraries(project: Project, libraryPaths: Collection): Boolean = - GradleSettings.getInstance(project).linkedProjectsSettings.isNotEmpty() - - override fun getKonanHome(project: Project): Path? { - val projectNode = ProjectDataManager.getInstance().getExternalProjectsData(project, GradleConstants.SYSTEM_ID) - .mapNotNull { it.externalProjectStructure } - .firstOrNull() ?: return null - projectNode.getUserData(KONAN_HOME)?.let { return it } - - var konanHomePath: Path? = null - find(projectNode, ProjectKeys.MODULE, BooleanFunction { moduleNode -> - find(moduleNode, KonanProjectResolver.KONAN_MODEL_KEY, BooleanFunction { konanModelNode -> - konanHomePath = konanModelNode.data.konanHome.toPath() - projectNode.putUserData(KONAN_HOME, konanHomePath) - konanHomePath != null - }) != null - }) - return konanHomePath - } - - override fun getArtifacts(project: Project): Collection { - val artifacts = mutableListOf() - ProjectDataManager.getInstance().getExternalProjectsData(project, GradleConstants.SYSTEM_ID) - .mapNotNull { it.externalProjectStructure } - .forEach { projectStructure -> - findAll(projectStructure, ProjectKeys.MODULE) - .map { Pair(it.data.externalName, find(it, KonanProjectResolver.KONAN_MODEL_KEY)) } - .filter { it.second != null } - .forEach { (moduleName, konanProjectNode) -> - konanProjectNode!!.data.artifacts.forEach { konanArtifact -> - val sources = konanArtifact.srcFiles.map { it.toPath() } - - artifacts.add( - KonanArtifact( - konanArtifact.name, - moduleName, - konanArtifact.type, - konanTarget(konanProjectNode.data.konanHome, konanArtifact), - mutableListOf(), sources, konanArtifact.file.toPath() - ) - ) - } - } - } - return artifacts - } - - private fun konanTarget(konanHome: File, konanArtifactEx: KonanModelArtifact) = - PlatformManager(customerDistribution(konanHome.absolutePath)).targetValues.find { it.name == konanArtifactEx.targetPlatform } - - companion object { - val KONAN_HOME = Key.create("KONAN_HOME") - } + override fun getKonanHome(project: Project): Path? = null } diff --git a/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/KonanProjectDataService.kt b/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/KonanProjectDataService.kt deleted file mode 100644 index 1865e6dc33c..00000000000 --- a/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/KonanProjectDataService.kt +++ /dev/null @@ -1,75 +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.gradle - -import com.intellij.execution.RunManager -import com.intellij.execution.RunnerAndConfigurationSettings -import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.externalSystem.model.DataNode -import com.intellij.openapi.externalSystem.model.Key -import com.intellij.openapi.externalSystem.model.ProjectKeys -import com.intellij.openapi.externalSystem.model.project.ModuleData -import com.intellij.openapi.externalSystem.model.project.ProjectData -import com.intellij.openapi.externalSystem.service.project.IdeModelsProvider -import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider -import com.intellij.openapi.externalSystem.service.project.ProjectDataManager -import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService -import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil -import com.intellij.openapi.module.Module -import com.intellij.openapi.project.Project -import com.intellij.util.containers.ContainerUtil -import org.jetbrains.konan.settings.KonanArtifact -import org.jetbrains.konan.settings.KonanModelProvider -import org.jetbrains.konan.settings.isExecutable -import org.jetbrains.kotlin.gradle.plugin.model.KonanModel -import org.jetbrains.plugins.gradle.util.GradleConstants - -class KonanProjectDataService : AbstractProjectDataService() { - - override fun getTargetDataKey(): Key = KonanProjectResolver.KONAN_MODEL_KEY - - override fun postProcess( - toImport: Collection>, - projectData: ProjectData?, - project: Project, - modelsProvider: IdeModifiableModelsProvider - ) { - } - - override fun onSuccessImport( - imported: Collection>, - projectData: ProjectData?, - project: Project, - modelsProvider: IdeModelsProvider - ) { - if (projectData?.owner != GradleConstants.SYSTEM_ID) return - project.messageBus.syncPublisher(KonanModelProvider.RELOAD_TOPIC).run() - } - - companion object { - @JvmStatic - fun forEachKonanProject( - project: Project, - consumer: (konanProject: KonanModel, moduleData: ModuleData, rootProjectPath: String) -> Unit - ) { - for (projectInfo in ProjectDataManager.getInstance().getExternalProjectsData(project, GradleConstants.SYSTEM_ID)) { - val projectStructure = projectInfo.externalProjectStructure ?: continue - val projectData = projectStructure.data - val rootProjectPath = projectData.linkedExternalProjectPath - val modulesNodes = ExternalSystemApiUtil.findAll(projectStructure, ProjectKeys.MODULE) - for (moduleNode in modulesNodes) { - val projectNode = ExternalSystemApiUtil.find(moduleNode, KonanProjectResolver.KONAN_MODEL_KEY) - if (projectNode != null) { - val konanProject = projectNode.data - val moduleData = moduleNode.data - consumer(konanProject, moduleData, rootProjectPath) - } - } - } - } - } - -} diff --git a/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/KonanProjectResolver.kt b/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/KonanProjectResolver.kt deleted file mode 100644 index cb71c1203a0..00000000000 --- a/idea/idea-gradle/native/src/org/jetbrains/konan/gradle/KonanProjectResolver.kt +++ /dev/null @@ -1,157 +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.gradle - -import com.intellij.openapi.diagnostic.Logger -import com.intellij.openapi.externalSystem.model.DataNode -import com.intellij.openapi.externalSystem.model.Key -import com.intellij.openapi.externalSystem.model.ProjectKeys -import com.intellij.openapi.externalSystem.model.project.* -import com.intellij.util.containers.ContainerUtil.set -import com.intellij.util.io.isDirectory -import org.gradle.tooling.model.idea.IdeaModule -import org.jetbrains.kotlin.gradle.plugin.model.KonanModel -import org.jetbrains.kotlin.gradle.plugin.model.KonanModelArtifact -import org.jetbrains.kotlin.konan.KonanVersion -import org.jetbrains.kotlin.konan.MetaVersion -import org.jetbrains.kotlin.konan.target.CompilerOutputKind -import org.jetbrains.kotlin.konan.target.HostManager -import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension -import org.jetbrains.plugins.gradle.util.GradleConstants -import java.io.File -import java.nio.file.Files.isDirectory -import java.nio.file.Files.walk -import java.nio.file.Path -import java.util.* - -/** - * [KonanProjectResolver] creates IDE project model in terms of External System API - */ -class KonanProjectResolver : AbstractProjectResolverExtension() { - - // to ask gradle for the model - override fun getExtraProjectModelClasses(): Set> { - return set>(KonanModel::class.java) - } - - override fun populateModuleExtraModels(gradleModule: IdeaModule, ideModule: DataNode) { - resolverCtx.getExtraProject(gradleModule, KonanModel::class.java)?.let { - // store a local process copy of the object to get rid of proxy types for further serialization - ideModule.createChild(KONAN_MODEL_KEY, MyKonanModel(it)) - } - - nextResolver.populateModuleExtraModels(gradleModule, ideModule) - } - - override fun populateModuleContentRoots(gradleModule: IdeaModule, ideModule: DataNode) { - resolverCtx.getExtraProject(gradleModule, KonanModel::class.java)?.let { - val added = mutableSetOf() - for (artifact in it.artifacts) { - for (srcDir in artifact.srcDirs) { - val rootPath = srcDir.absolutePath - if (!added.add(rootPath)) continue - - val ideContentRoot = ContentRootData(GradleConstants.SYSTEM_ID, rootPath) - ideContentRoot.storePath(ExternalSystemSourceType.SOURCE, rootPath) - ideModule.createChild(ProjectKeys.CONTENT_ROOT, ideContentRoot) - } - } - } - - nextResolver.populateModuleContentRoots(gradleModule, ideModule) - } - - // based on KonanCMakeProjectComponent.reloadLibraries but with the multi-module projects support - override fun populateModuleDependencies( - gradleModule: IdeaModule, - ideModule: DataNode, - ideProject: DataNode - ) { - val konanModelEx = resolverCtx.getExtraProject(gradleModule, KonanModel::class.java) - if (konanModelEx != null) { - val libraryPaths = LinkedHashSet() - var konanHome: Path? = null - var targetPlatform: String? = null - for (konanArtifact in konanModelEx.artifacts) { - if (konanHome == null) { - konanHome = konanModelEx.konanHome.toPath() - targetPlatform = konanArtifact.targetPlatform - } - konanArtifact.libraries.forEach { libraryPaths.add(it.toPath()) } - } - - if (konanHome != null) { - // add konanStdlib copied from KonanPaths.konanStdlib - libraryPaths.add(konanHome.resolve("klib/common/stdlib")) - - // add konanPlatformLibraries, copied from KonanPaths.konanPlatformLibraries - if (targetPlatform != null) { - try { - val resolvedTargetName = HostManager.resolveAlias(targetPlatform) - val klibPath = konanHome.resolve("klib/platform/${resolvedTargetName}") - walk(klibPath, 1) - .filter { it.isDirectory() && it.fileName.toString() != "stdlib" && it != klibPath } - .forEach { libraryPaths.add(it) } - } catch (e: Exception) { - LOG.warn("Unable to collect konan platform libraries paths for '$targetPlatform'", e) - } - } - } - - val moduleData = ideModule.data - for (path in libraryPaths) { - val library = LibraryData(moduleData.owner, path.fileName.toString()) - library.addPath(LibraryPathType.BINARY, if (isDirectory(path)) path.toAbsolutePath().toString() else path.toString()) - - val data = LibraryDependencyData(moduleData, library, LibraryLevel.MODULE) - ideModule.createChild(ProjectKeys.LIBRARY_DEPENDENCY, data) - } - } - - nextResolver.populateModuleDependencies(gradleModule, ideModule, ideProject) - } - - private class MyKonanModel(konanModel: KonanModel) : KonanModel { - override val artifacts: List = konanModel.artifacts.map { MyKonanArtifactEx(it) } - override val konanHome: File = konanModel.konanHome - override val konanVersion: KonanVersion = MyKonanVersionEx(konanModel.konanVersion) - override val apiVersion: String? = konanModel.apiVersion - override val languageVersion: String? = konanModel.languageVersion - - private class MyKonanVersionEx(version: KonanVersion) : KonanVersion { - override val build: Int = version.build - override val maintenance: Int = version.maintenance - override val major: Int = version.major - override val meta: MetaVersion = version.meta - override val minor: Int = version.minor - - override fun toString(showMeta: Boolean, showBuild: Boolean): String { - val sb = StringBuilder("$major.$minor.$maintenance") - if (showMeta) sb.append('-').append(meta) - if (showBuild) sb.append('-').append(build) - return sb.toString() - } - } - - private class MyKonanArtifactEx(artifact: KonanModelArtifact) : KonanModelArtifact { - override val searchPaths: List = artifact.searchPaths - override val name: String = artifact.name - override val type: CompilerOutputKind = artifact.type - override val targetPlatform: String = artifact.targetPlatform - override val file: File = artifact.file - override val buildTaskName: String = artifact.buildTaskName - - override val srcDirs: List = artifact.srcDirs.toList() - override val srcFiles: List = artifact.srcFiles.toList() - override val libraries: List = artifact.libraries.toList() - } - } - - companion object { - val KONAN_MODEL_KEY = Key.create(KonanModel::class.java, ProjectKeys.MODULE.processingWeight + 1) - private val LOG = Logger.getInstance(KonanProjectResolver::class.java) - } -} diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt index 4ef0c918113..a063c5397d3 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt @@ -293,7 +293,7 @@ fun hasKotlinFilesInSources(module: Module): Boolean { return FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(false)) } -private class LibraryKindSearchScope( +class LibraryKindSearchScope( val module: Module, val baseScope: GlobalSearchScope, val libraryKind: PersistentLibraryKind<*> diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt index 21d11f562bb..d59f95726c4 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/configuration/KotlinWithLibraryConfigurator.kt @@ -33,7 +33,7 @@ import org.jetbrains.kotlin.idea.versions.findKotlinRuntimeLibrary import java.io.File import java.util.* -abstract class KotlinWithLibraryConfigurator internal constructor() : KotlinProjectConfigurator { +abstract class KotlinWithLibraryConfigurator protected constructor() : KotlinProjectConfigurator { protected abstract val libraryName: String protected abstract val messageForOverrideDialog: String diff --git a/idea/idea-native/build.gradle.kts b/idea/idea-native/build.gradle.kts index 2e911a7bedd..c227564e548 100644 --- a/idea/idea-native/build.gradle.kts +++ b/idea/idea-native/build.gradle.kts @@ -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() } } diff --git a/idea/idea-native/src/org/jetbrains/konan/analyser/KonanAnalyzerFacade.kt b/idea/idea-native/src/org/jetbrains/konan/analyser/KonanAnalyzerFacade.kt index d032da206d1..1268302cf81 100644 --- a/idea/idea-native/src/org/jetbrains/konan/analyser/KonanAnalyzerFacade.kt +++ b/idea/idea-native/src/org/jetbrains/konan/analyser/KonanAnalyzerFacade.kt @@ -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 diff --git a/idea/idea-native/src/org/jetbrains/konan/analyser/index/KonanDescriptorManager.kt b/idea/idea-native/src/org/jetbrains/konan/analyser/index/KonanDescriptorManager.kt index dba80606ec4..50df01367a1 100644 --- a/idea/idea-native/src/org/jetbrains/konan/analyser/index/KonanDescriptorManager.kt +++ b/idea/idea-native/src/org/jetbrains/konan/analyser/index/KonanDescriptorManager.kt @@ -16,8 +16,6 @@ class KonanDescriptorManager : ApplicationComponent { companion object { - private const val currentAbiVersion = 1 - @JvmStatic fun getInstance(): KonanDescriptorManager = ApplicationManager.getApplication().getComponent(KonanDescriptorManager::class.java) } diff --git a/idea/idea-native/src/org/jetbrains/konan/analyser/index/KonanMetaFileIndex.kt b/idea/idea-native/src/org/jetbrains/konan/analyser/index/KonanMetaFileIndex.kt index 00d16204ae8..58dd3e32773 100644 --- a/idea/idea-native/src/org/jetbrains/konan/analyser/index/KonanMetaFileIndex.kt +++ b/idea/idea-native/src/org/jetbrains/konan/analyser/index/KonanMetaFileIndex.kt @@ -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::class.java) { +object KonanMetaFileIndex : KotlinFileIndexBase(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) + } } diff --git a/idea/idea-native/src/org/jetbrains/konan/settings/KonanModelProvider.java b/idea/idea-native/src/org/jetbrains/konan/settings/KonanModelProvider.java index 912b8cabe45..2e636786009 100644 --- a/idea/idea-native/src/org/jetbrains/konan/settings/KonanModelProvider.java +++ b/idea/idea-native/src/org/jetbrains/konan/settings/KonanModelProvider.java @@ -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 EP_NAME = ExtensionPointName.create("org.jetbrains.kotlin.native.konanModelProvider"); - @NotNull - Collection getArtifacts(@NotNull Project project); - @Nullable Path getKonanHome(@NotNull Project project); - - boolean reloadLibraries(@NotNull Project project, @NotNull Collection libraryPaths); } diff --git a/idea/idea-native/src/org/jetbrains/konan/settings/KonanPaths.kt b/idea/idea-native/src/org/jetbrains/konan/settings/KonanPaths.kt index 629c8938d48..29828e9a840 100644 --- a/idea/idea-native/src/org/jetbrains/konan/settings/KonanPaths.kt +++ b/idea/idea-native/src/org/jetbrains/konan/settings/KonanPaths.kt @@ -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() } diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanModuleConfigurator.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanModuleConfigurator.kt new file mode 100644 index 00000000000..6b8656b2d8c --- /dev/null +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanModuleConfigurator.kt @@ -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() + + override val libraryMatcher: (Library, Project) -> Boolean = { library, _ -> + library.getFiles(OrderRootType.CLASSES).firstOrNull { it.nameWithoutExtension == KONAN_STDLIB_NAME } != null + } + + override val libraryType: LibraryType? 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) + } + } +} diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanPlatformKind.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanPlatformKind.kt new file mode 100644 index 00000000000..1ec014850c0 --- /dev/null +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanPlatformKind.kt @@ -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() { + + override fun platformByCompilerArguments(arguments: CommonCompilerArguments): IdePlatform? { + 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() { + 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 diff --git a/idea/idea-native/src/org/jetbrains/konan/analyser/KonanPlatformSupport.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanPlatformKindResolution.kt similarity index 58% rename from idea/idea-native/src/org/jetbrains/konan/analyser/KonanPlatformSupport.kt rename to idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanPlatformKindResolution.kt index 07145123c2e..570692e9a3f 100644 --- a/idea/idea-native/src/org/jetbrains/konan/analyser/KonanPlatformSupport.kt +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanPlatformKindResolution.kt @@ -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)) diff --git a/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanPlatformKindTooling.kt b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanPlatformKindTooling.kt new file mode 100644 index 00000000000..fe745639ec2 --- /dev/null +++ b/idea/idea-native/src/org/jetbrains/kotlin/ide/konan/KonanPlatformKindTooling.kt @@ -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 get() = emptyList() + override val gradlePluginId: String get() = "" + override val gradlePlatformIds: List 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("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) + } +} diff --git a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModel.kt b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModel.kt index ac7a3f04ed5..427a582f42a 100644 --- a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModel.kt +++ b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModel.kt @@ -60,6 +60,7 @@ enum class KotlinPlatform(val id: String) { COMMON("common"), JVM("jvm"), JS("js"), + KONAN("native"), ANDROID("androidJvm"); companion object { diff --git a/idea/src/META-INF/gradle.xml b/idea/src/META-INF/gradle.xml index 5201b4b795e..ceeb21e9da8 100644 --- a/idea/src/META-INF/gradle.xml +++ b/idea/src/META-INF/gradle.xml @@ -28,13 +28,4 @@ - - - - - - - - - diff --git a/idea/src/META-INF/native.xml b/idea/src/META-INF/native.xml index 5ce64f5a7ef..d852c302807 100644 --- a/idea/src/META-INF/native.xml +++ b/idea/src/META-INF/native.xml @@ -32,6 +32,10 @@ - - + + + + + + diff --git a/konan/serializer/build.gradle.kts b/konan/serializer/build.gradle.kts index 578497db494..074ea216add 100644 --- a/konan/serializer/build.gradle.kts +++ b/konan/serializer/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { // Compile-only dependencies are needed for compilation of this module: compileOnly(project(":compiler:frontend")) compileOnly(project(":compiler:frontend.java")) + compileOnly(project(":compiler:cli-common")) // This dependency is necessary to keep the right dependency record inside of POM file: compile(projectRuntimeJar(":kotlin-compiler")) diff --git a/konan/serializer/src/org/jetbrains/kotlin/cli/common/arguments/konan/K2NativeCompilerArguments.kt b/konan/serializer/src/org/jetbrains/kotlin/cli/common/arguments/konan/K2NativeCompilerArguments.kt new file mode 100644 index 00000000000..6d1b71b92fe --- /dev/null +++ b/konan/serializer/src/org/jetbrains/kotlin/cli/common/arguments/konan/K2NativeCompilerArguments.kt @@ -0,0 +1,148 @@ +/* + * 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.cli.common.arguments.konan + +import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.Argument +import org.jetbrains.kotlin.cli.common.messages.MessageCollector +import org.jetbrains.kotlin.config.AnalysisFlag + +class K2NativeCompilerArguments : CommonCompilerArguments() { + // First go the options interesting to the general public. + // Prepend them with a single dash. + // Keep the list lexically sorted. + + @Argument(value = "-enable_assertions", shortName = "-ea", description = "Enable runtime assertions in generated code") + var enableAssertions: Boolean = false + + @Argument(value = "-g", description = "Enable emitting debug information") + var debug: Boolean = false + + @Argument(value = "-generate_test_runner", shortName = "-tr", description = "Produce a runner for unit tests") + var generateTestRunner: Boolean = false + + @Argument(value = "-includeBinary", shortName = "-ib", valueDescription = "", description = "Pack external binary within the klib") + var includeBinaries: Array? = null + + @Argument(value = "-library", shortName = "-l", valueDescription = "", description = "Link with the library") + var libraries: Array? = null + + @Argument(value = "-list_targets", description = "List available hardware targets") + var listTargets: Boolean = false + + @Argument(value = "-manifest", valueDescription = "", description = "Provide a maniferst addend file") + var manifestFile: String? = null + + @Argument(value = "-module_name", valueDescription = "", description = "Spicify a name for the compilation module") + var moduleName: String? = null + + @Argument(value = "-nativelibrary", shortName = "-nl", valueDescription = "", description = "Include the native bitcode library") + var nativeLibraries: Array? = null + + @Argument(value = "-nodefaultlibs", description = "Don't link the libraries from dist/klib automatically") + var nodefaultlibs: Boolean = false + + @Argument(value = "-nomain", description = "Assume 'main' entry point to be provided by external libraries") + var nomain: Boolean = false + + @Argument(value = "-nopack", description = "Don't pack the library into a klib file") + var nopack: Boolean = false + + @Argument(value = "-linkerOpts", valueDescription = "", description = "Pass arguments to linker", delimiter = " ") + var linkerArguments: Array? = null + + @Argument(value = "-nostdlib", description = "Don't link with stdlib") + var nostdlib: Boolean = false + + @Argument(value = "-opt", description = "Enable optimizations during compilation") + var optimization: Boolean = false + + @Argument(value = "-output", shortName = "-o", valueDescription = "", description = "Output name") + var outputName: String? = null + + @Argument(value = "-entry", shortName = "-e", valueDescription = "", description = "Qualified entry point name") + var mainPackage: String? = null + + @Argument(value = "-produce", shortName = "-p", + valueDescription = "{program|static|dynamic|framework|library|bitcode}", + description = "Specify output file kind") + var produce: String? = null + + @Argument(value = "-repo", shortName = "-r", valueDescription = "", description = "Library search path") + var repositories: Array? = null + + @Argument(value = "-target", valueDescription = "", description = "Set hardware target") + var target: String? = null + + // The rest of the options are only interesting to the developers. + // Make sure to prepend them with a double dash. + // Keep the list lexically sorted. + + @Argument(value = "--check_dependencies", description = "Check dependencies and download the missing ones") + var checkDependencies: Boolean = false + + @Argument(value = "--disable", valueDescription = "", description = "Disable backend phase") + var disablePhases: Array? = null + + @Argument(value = "--enable", valueDescription = "", description = "Enable backend phase") + var enablePhases: Array? = null + + @Argument(value = "--list_phases", description = "List all backend phases") + var listPhases: Boolean = false + + @Argument(value = "--print_bitcode", description = "Print llvm bitcode") + var printBitCode: Boolean = false + + @Argument(value = "--print_descriptors", description = "Print descriptor tree") + var printDescriptors: Boolean = false + + @Argument(value = "--print_ir", description = "Print IR") + var printIr: Boolean = false + + @Argument(value = "--print_ir_with_descriptors", description = "Print IR with descriptors") + var printIrWithDescriptors: Boolean = false + + @Argument(value = "--print_locations", description = "Print locations") + var printLocations: Boolean = false + + @Argument(value = "--purge_user_libs", description = "Don't link unused libraries even explicitly specified") + var purgeUserLibs: Boolean = false + + @Argument(value = "--runtime", valueDescription = "", description = "Override standard 'runtime.bc' location") + var runtimeFile: String? = null + + @Argument(value = "--temporary_files_dir", valueDescription = "", description = "Save temporary files to the given directory") + var temporaryFilesDir: String? = null + + @Argument(value = "--time", description = "Report execution time for compiler phases") + var timePhases: Boolean = false + + @Argument(value = "--verbose", valueDescription = "", description = "Trace phase execution") + var verbosePhases: Array? = null + + @Argument(value = "--verify_bitcode", description = "Verify llvm bitcode after each method") + var verifyBitCode: Boolean = false + + @Argument(value = "--verify_descriptors", description = "Verify descriptor tree") + var verifyDescriptors: Boolean = false + + @Argument(value = "--verify_ir", description = "Verify IR") + var verifyIr: Boolean = false + + @Argument( + value = "-friend-modules", + valueDescription = "", + description = "Paths to friend modules" + ) + var friendModules: String? = null + + override fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> = + super.configureAnalysisFlags(collector).also { + val useExperimental = it[AnalysisFlag.useExperimental] as List<*> + it[AnalysisFlag.useExperimental] = useExperimental + listOf("kotlin.ExperimentalUnsignedTypes") + } +} + diff --git a/prepare/idea-plugin/build.gradle.kts b/prepare/idea-plugin/build.gradle.kts index a1cad8fbe71..9f3d593b1af 100644 --- a/prepare/idea-plugin/build.gradle.kts +++ b/prepare/idea-plugin/build.gradle.kts @@ -37,7 +37,7 @@ val projectsToShadow by extra(listOf( ":idea:idea-native", ":idea:idea-core", ":idea:idea-gradle", - //":idea:idea-gradle:native", + ":idea:idea-gradle:native", //":idea-ultimate", ":compiler:ir.psi2ir", ":compiler:ir.tree", diff --git a/settings.gradle b/settings.gradle index cff861c5938..85f0d1567ae 100644 --- a/settings.gradle +++ b/settings.gradle @@ -77,7 +77,7 @@ include ":kotlin-build-common", ":idea:idea-android-output-parser", ":idea:idea-test-framework", ":idea:idea-native", - //":idea:idea-gradle:native", + ":idea:idea-gradle:native", ":idea", ":idea-runner", ":eval4j",