From 075a0bc7f1e5ab45abbc355860a0f2c82d4f28b5 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 10 Nov 2016 15:43:02 +0300 Subject: [PATCH] Kotlin Facet: Configure facet automatically on Gradle project import --- .../kotlin/idea/maven/KotlinMavenImporter.kt | 20 ++----- idea/src/META-INF/gradle.xml | 2 + .../KotlinGradleProjectDataService.kt | 53 +++++++++++++++++++ .../jetbrains/kotlin/idea/facet/facetUtils.kt | 16 ++++++ .../DifferentStdlibGradleVersionInspection.kt | 25 +++++---- .../gradle/KotlinGradleInspectionVisitor.kt | 2 +- 6 files changed, 92 insertions(+), 26 deletions(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/configuration/KotlinGradleProjectDataService.kt diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt index fca3c51dae2..d6a249abf64 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenImporter.kt @@ -35,6 +35,7 @@ import org.jetbrains.jps.model.java.JavaSourceRootType import org.jetbrains.jps.model.module.JpsModuleSourceRootType import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.config.TargetPlatformKind +import org.jetbrains.kotlin.idea.facet.configureFacet import org.jetbrains.kotlin.idea.facet.getOrCreateFacet import org.jetbrains.kotlin.idea.facet.initializeIfNeeded import org.jetbrains.kotlin.idea.facet.mavenLibraryId @@ -90,22 +91,9 @@ class KotlinMavenImporter : MavenImporter(KotlinPluginGroupId, KotlinPluginArtif } private fun configureFacet(mavenProject: MavenProject, modifiableModelsProvider: IdeModifiableModelsProvider, module: Module) { - val compilerVersion = mavenProject.findPlugin(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID)?.version ?: return - val artifacts = mavenProject.dependencyArtifactIndex.data[KotlinPluginGroupId]?.values?.flatMap { it.filter { it.isResolved } } - val expectedLibraryIds = TargetPlatformKind.ALL_PLATFORMS.map { it.mavenLibraryId } - val stdlibArtifact = artifacts?.firstOrNull { it.artifactId in expectedLibraryIds } - - val facet = module.getOrCreateFacet(modifiableModelsProvider) - with(facet.configuration.settings.versionInfo) { - targetPlatformKind = null - apiLevel = null - facet.configuration.settings.initializeIfNeeded(module, modifiableModelsProvider.getModifiableRootModel(module)) - languageLevel = LanguageVersion.fromFullVersionString(compilerVersion) - // Both apiLevel and languageLevel should be initialized in the lines above - if (apiLevel!! > languageLevel!!) { - apiLevel = languageLevel - } - } + val compilerVersion = mavenProject.findPlugin(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID)?.version + ?: return + module.getOrCreateFacet(modifiableModelsProvider).configureFacet(compilerVersion, modifiableModelsProvider) } // TODO in theory it should work like this but it doesn't as it couldn't unmark source roots that are not roots anymore. diff --git a/idea/src/META-INF/gradle.xml b/idea/src/META-INF/gradle.xml index 6f8b70b9c34..036de587a2a 100644 --- a/idea/src/META-INF/gradle.xml +++ b/idea/src/META-INF/gradle.xml @@ -9,6 +9,8 @@ + + () { + override fun getTargetDataKey() = GradleSourceSetData.KEY + + override fun postProcess( + toImport: Collection>, + projectData: ProjectData?, + project: Project, + modelsProvider: IdeModifiableModelsProvider + ) { + for (sourceSetNode in toImport) { + val sourceSetData = sourceSetNode.data + val ideModule = modelsProvider.findIdeModule(sourceSetData) ?: continue + + val moduleNode = ExternalSystemApiUtil.findParent(sourceSetNode, ProjectKeys.MODULE) + val compilerVersion = moduleNode?.findAll(BuildScriptClasspathData.KEY)?.firstOrNull()?.data?.let(::findKotlinPluginVersion) + ?: continue + + ideModule.getOrCreateFacet(modelsProvider).configureFacet(compilerVersion, modelsProvider) + } + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index e329bb3d841..4d524838efc 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -146,3 +146,19 @@ fun Module.getOrCreateFacet(modelsProvider: IdeModifiableModelsProvider): Kotlin facetModel.addFacet(facet) return facet } + +fun KotlinFacet.configureFacet(compilerVersion: String, modelsProvider: IdeModifiableModelsProvider) { + val module = module + with(configuration.settings) { + versionInfo.targetPlatformKind = null + versionInfo.apiLevel = null + initializeIfNeeded(module, modelsProvider.getModifiableRootModel(module)) + with(versionInfo) { + languageLevel = LanguageVersion.fromFullVersionString(compilerVersion) ?: LanguageVersion.LATEST + // Both apiLevel and languageLevel should be initialized in the lines above + if (apiLevel!! > languageLevel!!) { + apiLevel = languageLevel + } + } + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/gradle/DifferentStdlibGradleVersionInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/gradle/DifferentStdlibGradleVersionInspection.kt index d7429e4b3d5..25d98d7adee 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/gradle/DifferentStdlibGradleVersionInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/gradle/DifferentStdlibGradleVersionInspection.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.idea.inspections.gradle +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 @@ -50,7 +51,7 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() { if (dependenciesCall.parent !is PsiFile) return val stdlibStatement = findLibraryStatement(closure, "org.jetbrains.kotlin", libraryId) ?: return - val stdlibVersion = getResolvedKotlinStdlibVersion(closure.containingFile, "org.jetbrains.kotlin:$libraryId:") ?: return + val stdlibVersion = getResolvedKotlinStdlibVersion(closure.containingFile, libraryId) ?: return onFound(stdlibVersion, stdlibStatement) } @@ -99,21 +100,27 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() { return null } - private fun getResolvedKotlinStdlibVersion(file: PsiFile, libraryNameMarker: String): String? { + private fun getResolvedKotlinStdlibVersion(file: PsiFile, libraryId: 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 }) { - for (sourceSetData in moduleData.node.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) - } - } - } + moduleData.node.getResolvedKotlinStdlibVersionByModuleData(libraryId)?.let { return it } } return null } } +} + +internal fun DataNode<*>.getResolvedKotlinStdlibVersionByModuleData(libraryId: String): String? { + val libraryNameMarker = "org.jetbrains.kotlin:$libraryId:" + 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) + } + } + } + return null } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/gradle/KotlinGradleInspectionVisitor.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/gradle/KotlinGradleInspectionVisitor.kt index edf0464f686..49ae781773b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/gradle/KotlinGradleInspectionVisitor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/gradle/KotlinGradleInspectionVisitor.kt @@ -72,7 +72,7 @@ fun getResolvedKotlinGradleVersion(module: Module): String? { return null } -private fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): String? { +internal fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): String? { for (classPathEntry in classpathData.classpathEntries) { for (path in classPathEntry.classesFile) { val uniformedPath = path.replace('\\', '/')