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:idea-jvm"))
compileOnly(project(":idea:idea-native")) { isTransitive = false }
compile(project(":idea:kotlin-gradle-tooling"))
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.impl.libraries.LibraryEx
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.util.Key
import com.intellij.util.PathUtil
@@ -40,6 +41,7 @@ import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.gradle.ArgsInfo
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.configuration.GradlePropertiesFileFacade.Companion.KOTLIN_CODE_STYLE_GRADLE_SETTING
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.platform.tooling
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.impl.isCommon
import org.jetbrains.kotlin.platform.impl.isJavaScript
@@ -173,15 +176,24 @@ class KotlinGradleLibraryDataService : AbstractProjectDataService<LibraryData, V
val ideLibrary = modelsProvider.findIdeLibrary(libraryDataNode.data) ?: continue
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 }
} 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)
}
}
}
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) {
try {
@@ -203,7 +215,7 @@ class KotlinGradleLibraryDataService : AbstractProjectDataService<LibraryData, V
companion object {
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()
}
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_LEGACY_GROUP_ID = KOTLIN_NATIVE_LIBRARY_PREFIX
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.roots.libraries.DummyLibraryProperties
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.vfs.VirtualFile
import com.intellij.util.PathUtil
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.JComponent
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(
parentComponent: JComponent,
contextDirectory: VirtualFile?,
project: Project
): NewLibraryConfiguration? = null
return if (LiteKonanLibraryFacade.getLibraryProvider().getLibrary(File(path)) != null)
DummyLibraryProperties.INSTANCE!!
else null
}
override fun getIcon(properties: DummyLibraryProperties?): Icon = KotlinIcons.NATIVE
}
@@ -24,7 +24,6 @@ object LiteKonanLibraryFacade {
*/
fun getDistributionLibraryProvider(customKonanHomeDir: File?): LiteKonanLibraryProvider =
FromDistributionLiteKonanLibraryProvider(customKonanHomeDir)
}
interface LiteKonanLibraryProvider {