Properly detect Kotlin/Native libraries

Issue #KT-30598 fixed
This commit is contained in:
Dmitriy Dolovov
2019-04-26 20:09:56 +07:00
parent 20d77afcce
commit c017ef9bc8
5 changed files with 33 additions and 14 deletions
+1
View File
@@ -8,6 +8,7 @@ dependencies {
compileOnly(project(":idea")) compileOnly(project(":idea"))
compileOnly(project(":idea:idea-jvm")) compileOnly(project(":idea:idea-jvm"))
compileOnly(project(":idea:idea-native")) { isTransitive = false }
compile(project(":idea:kotlin-gradle-tooling")) compile(project(":idea:kotlin-gradle-tooling"))
compile(project(":compiler:frontend")) compile(project(":compiler:frontend"))
@@ -30,6 +30,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderRootType import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.impl.libraries.LibraryEx import com.intellij.openapi.roots.impl.libraries.LibraryEx
import com.intellij.openapi.roots.impl.libraries.LibraryImpl import com.intellij.openapi.roots.impl.libraries.LibraryImpl
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.roots.libraries.PersistentLibraryKind import com.intellij.openapi.roots.libraries.PersistentLibraryKind
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import com.intellij.util.PathUtil import com.intellij.util.PathUtil
@@ -40,6 +41,7 @@ import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.gradle.ArgsInfo import org.jetbrains.kotlin.gradle.ArgsInfo
import org.jetbrains.kotlin.gradle.CompilerArgumentsBySourceSet import org.jetbrains.kotlin.gradle.CompilerArgumentsBySourceSet
import org.jetbrains.kotlin.ide.konan.NativeLibraryKind
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.configuration.GradlePropertiesFileFacade.Companion.KOTLIN_CODE_STYLE_GRADLE_SETTING import org.jetbrains.kotlin.idea.configuration.GradlePropertiesFileFacade.Companion.KOTLIN_CODE_STYLE_GRADLE_SETTING
import org.jetbrains.kotlin.idea.facet.* import org.jetbrains.kotlin.idea.facet.*
@@ -52,6 +54,7 @@ import org.jetbrains.kotlin.idea.inspections.gradle.findKotlinPluginVersion
import org.jetbrains.kotlin.idea.inspections.gradle.getResolvedVersionByModuleData import org.jetbrains.kotlin.idea.inspections.gradle.getResolvedVersionByModuleData
import org.jetbrains.kotlin.idea.platform.tooling import org.jetbrains.kotlin.idea.platform.tooling
import org.jetbrains.kotlin.idea.roots.migrateNonJvmSourceFolders import org.jetbrains.kotlin.idea.roots.migrateNonJvmSourceFolders
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION
import org.jetbrains.kotlin.platform.IdePlatformKind import org.jetbrains.kotlin.platform.IdePlatformKind
import org.jetbrains.kotlin.platform.impl.isCommon import org.jetbrains.kotlin.platform.impl.isCommon
import org.jetbrains.kotlin.platform.impl.isJavaScript import org.jetbrains.kotlin.platform.impl.isJavaScript
@@ -173,15 +176,24 @@ class KotlinGradleLibraryDataService : AbstractProjectDataService<LibraryData, V
val ideLibrary = modelsProvider.findIdeLibrary(libraryDataNode.data) ?: continue val ideLibrary = modelsProvider.findIdeLibrary(libraryDataNode.data) ?: continue
val modifiableModel = modelsProvider.getModifiableLibraryModel(ideLibrary) as LibraryEx.ModifiableModelEx val modifiableModel = modelsProvider.getModifiableLibraryModel(ideLibrary) as LibraryEx.ModifiableModelEx
if (anyNonJvmModules || ideLibrary.name?.looksAsNonJvmLibraryName() == true) { if (anyNonJvmModules || ideLibrary.looksAsNonJvmLibrary()) {
detectLibraryKind(modifiableModel.getFiles(OrderRootType.CLASSES))?.let { modifiableModel.kind = it } detectLibraryKind(modifiableModel.getFiles(OrderRootType.CLASSES))?.let { modifiableModel.kind = it }
} else if (ideLibrary is LibraryImpl && (ideLibrary.kind === JSLibraryKind || ideLibrary.kind === CommonLibraryKind)) { } else if (ideLibrary is LibraryImpl
&& (ideLibrary.kind === JSLibraryKind || ideLibrary.kind === NativeLibraryKind || ideLibrary.kind === CommonLibraryKind)
) {
resetLibraryKind(modifiableModel) resetLibraryKind(modifiableModel)
} }
} }
} }
private fun String.looksAsNonJvmLibraryName() = nonJvmSuffixes.any { it in this } private fun Library.looksAsNonJvmLibrary(): Boolean {
name?.let { name ->
if (nonJvmSuffixes.any { it in name } || name.startsWith(KOTLIN_NATIVE_LIBRARY_PREFIX))
return true
}
return getFiles(OrderRootType.CLASSES).firstOrNull()?.extension == KLIB_FILE_EXTENSION
}
private fun resetLibraryKind(modifiableModel: LibraryEx.ModifiableModelEx) { private fun resetLibraryKind(modifiableModel: LibraryEx.ModifiableModelEx) {
try { try {
@@ -203,7 +215,7 @@ class KotlinGradleLibraryDataService : AbstractProjectDataService<LibraryData, V
companion object { companion object {
val LOG = Logger.getInstance(KotlinGradleLibraryDataService::class.java) val LOG = Logger.getInstance(KotlinGradleLibraryDataService::class.java)
val nonJvmSuffixes = listOf("-common", "-js", "-native", "-kjsm") val nonJvmSuffixes = listOf("-common", "-js", "-native", "-kjsm", "-metadata")
} }
} }
@@ -242,7 +242,7 @@ private sealed class DependencySubstitute {
class YesSubstitute(val substitute: ExternalMultiLibraryDependency) : DependencySubstitute() class YesSubstitute(val substitute: ExternalMultiLibraryDependency) : DependencySubstitute()
} }
private const val KOTLIN_NATIVE_LIBRARY_PREFIX = "Kotlin/Native" internal const val KOTLIN_NATIVE_LIBRARY_PREFIX = "Kotlin/Native"
private const val KOTLIN_NATIVE_LIBRARY_PREFIX_PLUS_SPACE = "$KOTLIN_NATIVE_LIBRARY_PREFIX " private const val KOTLIN_NATIVE_LIBRARY_PREFIX_PLUS_SPACE = "$KOTLIN_NATIVE_LIBRARY_PREFIX "
private const val KOTLIN_NATIVE_LEGACY_GROUP_ID = KOTLIN_NATIVE_LIBRARY_PREFIX private const val KOTLIN_NATIVE_LEGACY_GROUP_ID = KOTLIN_NATIVE_LIBRARY_PREFIX
private const val GRADLE_LIBRARY_PREFIX = "Gradle: " private const val GRADLE_LIBRARY_PREFIX = "Gradle: "
@@ -8,23 +8,30 @@ package org.jetbrains.kotlin.ide.konan
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.libraries.DummyLibraryProperties import com.intellij.openapi.roots.libraries.DummyLibraryProperties
import com.intellij.openapi.roots.libraries.LibraryType import com.intellij.openapi.roots.libraries.LibraryType
import com.intellij.openapi.roots.libraries.NewLibraryConfiguration
import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.PathUtil
import org.jetbrains.kotlin.idea.KotlinIcons import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.konan.library.lite.LiteKonanLibraryFacade
import java.io.File
import javax.swing.Icon import javax.swing.Icon
import javax.swing.JComponent import javax.swing.JComponent
object NativeLibraryType : LibraryType<DummyLibraryProperties>(NativeLibraryKind) { object NativeLibraryType : LibraryType<DummyLibraryProperties>(NativeLibraryKind) {
override fun createPropertiesEditor(editorComponent: LibraryEditorComponent<DummyLibraryProperties>) = null override fun createPropertiesEditor(editorComponent: LibraryEditorComponent<DummyLibraryProperties>): Nothing? = null
override fun getCreateActionName(): Nothing? = null
override fun createNewLibrary(parentComponent: JComponent, contextDirectory: VirtualFile?, project: Project): Nothing? = null
override fun getCreateActionName() = null // Library type is determined by `KotlinGradleLibraryDataService` for every library dependency imported from Gradle to IDE.
// However this does not work for libraries that are to be just created during project build, e.g. C-interop Kotlin/Native KLIBs.
// The code below helps to perform postponed detection of Kotlin/Native libraries.
override fun detect(classesRoots: List<VirtualFile>): DummyLibraryProperties? {
val path = classesRoots.firstOrNull()?.let { PathUtil.getLocalPath(it) } ?: return null
override fun createNewLibrary( return if (LiteKonanLibraryFacade.getLibraryProvider().getLibrary(File(path)) != null)
parentComponent: JComponent, DummyLibraryProperties.INSTANCE!!
contextDirectory: VirtualFile?, else null
project: Project }
): NewLibraryConfiguration? = null
override fun getIcon(properties: DummyLibraryProperties?): Icon = KotlinIcons.NATIVE override fun getIcon(properties: DummyLibraryProperties?): Icon = KotlinIcons.NATIVE
} }
@@ -24,7 +24,6 @@ object LiteKonanLibraryFacade {
*/ */
fun getDistributionLibraryProvider(customKonanHomeDir: File?): LiteKonanLibraryProvider = fun getDistributionLibraryProvider(customKonanHomeDir: File?): LiteKonanLibraryProvider =
FromDistributionLiteKonanLibraryProvider(customKonanHomeDir) FromDistributionLiteKonanLibraryProvider(customKonanHomeDir)
} }
interface LiteKonanLibraryProvider { interface LiteKonanLibraryProvider {