Kotlin Facet: Support multiple artifact Ids corresponding to target platform

This commit is contained in:
Alexey Sedunov
2017-02-01 16:34:31 +03:00
parent aa3f64bc93
commit 79e67f4e50
6 changed files with 36 additions and 28 deletions
@@ -144,7 +144,9 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
}
private fun detectPlatformByLibraries(mavenProject: MavenProject): TargetPlatformKind<*>? {
return TargetPlatformKind.ALL_PLATFORMS.firstOrNull { mavenProject.findDependencies(KOTLIN_PLUGIN_GROUP_ID, it.mavenLibraryId).isNotEmpty() }
return TargetPlatformKind.ALL_PLATFORMS.firstOrNull {
it.mavenLibraryIds.any { mavenProject.findDependencies(KOTLIN_PLUGIN_GROUP_ID, it).isNotEmpty() }
}
}
// TODO in theory it should work like this but it doesn't as it couldn't unmark source roots that are not roots anymore.
@@ -20,7 +20,7 @@ import com.intellij.openapi.module.Module
import org.jetbrains.idea.maven.project.MavenProjectsManager
import org.jetbrains.kotlin.config.TargetPlatformKind
import org.jetbrains.kotlin.idea.facet.KotlinVersionInfoProvider
import org.jetbrains.kotlin.idea.facet.mavenLibraryId
import org.jetbrains.kotlin.idea.facet.mavenLibraryIds
import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator
class MavenKotlinVersionInfoProvider : KotlinVersionInfoProvider {
@@ -33,6 +33,10 @@ class MavenKotlinVersionInfoProvider : KotlinVersionInfoProvider {
override fun getLibraryVersions(module: Module, targetPlatform: TargetPlatformKind<*>): Collection<String> {
val projectsManager = MavenProjectsManager.getInstance(module.project)
val mavenProject = projectsManager.findProject(module) ?: return emptyList()
return mavenProject.findDependencies(KotlinMavenConfigurator.GROUP_ID, targetPlatform.mavenLibraryId).map { it.version }.distinct()
return targetPlatform
.mavenLibraryIds
.flatMap { mavenProject.findDependencies(KotlinMavenConfigurator.GROUP_ID, it) }
.map { it.version }
.distinct()
}
}
@@ -20,7 +20,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.module.Module
import org.jetbrains.kotlin.config.TargetPlatformKind
import org.jetbrains.kotlin.idea.facet.KotlinVersionInfoProvider
import org.jetbrains.kotlin.idea.facet.mavenLibraryId
import org.jetbrains.kotlin.idea.facet.mavenLibraryIds
import org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection
import org.jetbrains.kotlin.idea.inspections.gradle.DifferentStdlibGradleVersionInspection
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
@@ -47,7 +47,7 @@ class GradleKotlinVersionInfoProvider : KotlinVersionInfoProvider {
override fun getLibraryVersions(module: Module, targetPlatform: TargetPlatformKind<*>): Collection<String> {
return runReadAction {
getGradleFile(module)?.let {
DifferentStdlibGradleVersionInspection.getKotlinStdlibVersions(it, targetPlatform.mavenLibraryId)
DifferentStdlibGradleVersionInspection.getKotlinStdlibVersions(it, targetPlatform.mavenLibraryIds)
}
} ?: emptyList()
}
@@ -103,7 +103,7 @@ private fun detectPlatformByPlugin(moduleNode: DataNode<ModuleData>): TargetPlat
}
private fun detectPlatformByLibrary(moduleNode: DataNode<ModuleData>): TargetPlatformKind<*>? {
return TargetPlatformKind.ALL_PLATFORMS.firstOrNull { moduleNode.getResolvedKotlinStdlibVersionByModuleData(it.mavenLibraryId) != null }
return TargetPlatformKind.ALL_PLATFORMS.firstOrNull { moduleNode.getResolvedKotlinStdlibVersionByModuleData(it.mavenLibraryIds) != null }
}
private fun configureFacetByGradleModule(
@@ -34,10 +34,7 @@ import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgu
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings
import org.jetbrains.kotlin.idea.framework.JSLibraryStdPresentationProvider
import org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider
import org.jetbrains.kotlin.idea.versions.MAVEN_COMMON_STDLIB_ID
import org.jetbrains.kotlin.idea.versions.MAVEN_JS_STDLIB_ID
import org.jetbrains.kotlin.idea.versions.MAVEN_STDLIB_ID
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
import org.jetbrains.kotlin.idea.versions.*
private fun getRuntimeLibraryVersions(
module: Module,
@@ -145,11 +142,11 @@ fun KotlinFacetSettings.initializeIfNeeded(module: Module, rootModel: ModuleRoot
}
}
val TargetPlatformKind<*>.mavenLibraryId: String
val TargetPlatformKind<*>.mavenLibraryIds: List<String>
get() = when (this) {
is TargetPlatformKind.Jvm -> MAVEN_STDLIB_ID
is TargetPlatformKind.JavaScript -> MAVEN_JS_STDLIB_ID
is TargetPlatformKind.Common -> MAVEN_COMMON_STDLIB_ID
is TargetPlatformKind.Jvm -> listOf(MAVEN_STDLIB_ID, MAVEN_STDLIB_ID_JRE7, MAVEN_STDLIB_ID_JRE8)
is TargetPlatformKind.JavaScript -> listOf(MAVEN_JS_STDLIB_ID)
is TargetPlatformKind.Common -> listOf(MAVEN_COMMON_STDLIB_ID)
}
fun Module.getOrCreateFacet(modelsProvider: IdeModifiableModelsProvider, useProjectSettings: Boolean): KotlinFacet {
@@ -20,6 +20,9 @@ import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.ProjectKeys
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.versions.MAVEN_STDLIB_ID
import org.jetbrains.kotlin.idea.versions.MAVEN_STDLIB_ID_JRE7
import org.jetbrains.kotlin.idea.versions.MAVEN_STDLIB_ID_JRE8
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.plugins.gradle.codeInspection.GradleBaseInspection
@@ -34,12 +37,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrC
import java.util.*
class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
override fun buildVisitor(): BaseInspectionVisitor = MyVisitor("kotlin-stdlib")
override fun buildVisitor(): BaseInspectionVisitor = MyVisitor(listOf(MAVEN_STDLIB_ID, MAVEN_STDLIB_ID_JRE7, MAVEN_STDLIB_ID_JRE8))
override fun buildErrorString(vararg args: Any) =
"Plugin version (${args[0]}) is not the same as library version (${args[1]})"
private abstract class VersionFinder(private val libraryId: String) : KotlinGradleInspectionVisitor() {
private abstract class VersionFinder(private val libraryIds: List<String>) : KotlinGradleInspectionVisitor() {
protected abstract fun onFound(stdlibVersion: String, stdlibStatement: GrCallExpression)
override fun visitClosure(closure: GrClosableBlock) {
@@ -50,14 +53,14 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
if (dependenciesCall.parent !is PsiFile) return
val stdlibStatement = findLibraryStatement(closure, "org.jetbrains.kotlin", libraryId) ?: return
val stdlibVersion = getResolvedKotlinStdlibVersion(closure.containingFile, libraryId) ?: return
val stdlibStatement = findLibraryStatement(closure, "org.jetbrains.kotlin", libraryIds) ?: return
val stdlibVersion = getResolvedKotlinStdlibVersion(closure.containingFile, libraryIds) ?: return
onFound(stdlibVersion, stdlibStatement)
}
}
private inner class MyVisitor(libraryId: String): VersionFinder(libraryId) {
private inner class MyVisitor(libraryIds: List<String>): VersionFinder(libraryIds) {
override fun onFound(stdlibVersion: String, stdlibStatement: GrCallExpression) {
val gradlePluginVersion = getResolvedKotlinGradleVersion(stdlibStatement.containingFile)
@@ -70,7 +73,7 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
companion object {
val COMPILE_DEPENDENCY_STATEMENTS = listOf("classpath", "compile")
fun getKotlinStdlibVersions(gradleFile: GroovyFileBase, libraryId: String): Collection<String> {
fun getKotlinStdlibVersions(gradleFile: GroovyFileBase, libraryId: List<String>): Collection<String> {
val versions = LinkedHashSet<String>()
val visitor = object : VersionFinder(libraryId) {
override fun visitElement(element: GroovyPsiElement) {
@@ -85,13 +88,13 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
return versions
}
private fun findLibraryStatement(closure: GrClosableBlock, libraryGroup: String, libraryId: String): GrCallExpression? {
private fun findLibraryStatement(closure: GrClosableBlock, libraryGroup: String, libraryIds: List<String>): GrCallExpression? {
val applicationStatements = closure.getChildrenOfType<GrCallExpression>()
for (statement in applicationStatements) {
val startExpression = statement.getChildrenOfType<GrReferenceExpression>().firstOrNull() ?: continue
if (startExpression.text in COMPILE_DEPENDENCY_STATEMENTS) {
if (statement.text.contains(libraryId) && statement.text.contains(libraryGroup)) {
if (libraryIds.any { it in statement.text } && statement.text.contains(libraryGroup)) {
return statement
}
}
@@ -100,12 +103,12 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
return null
}
private fun getResolvedKotlinStdlibVersion(file: PsiFile, libraryId: String): String? {
private fun getResolvedKotlinStdlibVersion(file: PsiFile, libraryIds: List<String>): String? {
val projectStructureNode = findGradleProjectStructure(file) ?: return null
val module = ProjectRootManager.getInstance(file.project).fileIndex.getModuleForFile(file.virtualFile) ?: return null
for (moduleData in projectStructureNode.findAll(ProjectKeys.MODULE).filter { it.data.internalName == module.name }) {
moduleData.node.getResolvedKotlinStdlibVersionByModuleData(libraryId)?.let { return it }
moduleData.node.getResolvedKotlinStdlibVersionByModuleData(libraryIds)?.let { return it }
}
return null
@@ -113,12 +116,14 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
}
}
internal fun DataNode<*>.getResolvedKotlinStdlibVersionByModuleData(libraryId: String): String? {
val libraryNameMarker = "org.jetbrains.kotlin:$libraryId"
internal fun DataNode<*>.getResolvedKotlinStdlibVersionByModuleData(libraryIds: List<String>): String? {
for (sourceSetData in findAll(GradleSourceSetData.KEY).filter { it.data.internalName.endsWith("main") }) {
for (libraryDependencyData in sourceSetData.node.findAll(ProjectKeys.LIBRARY_DEPENDENCY)) {
if (libraryDependencyData.data.externalName.startsWith(libraryNameMarker)) {
return libraryDependencyData.data.externalName.substringAfter(libraryNameMarker).substringAfter(':')
for (libraryId in libraryIds) {
val libraryNameMarker = "org.jetbrains.kotlin:$libraryId:"
if (libraryDependencyData.data.externalName.startsWith(libraryNameMarker)) {
return libraryDependencyData.data.externalName.substringAfter(libraryNameMarker)
}
}
}
}