mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-04 08:31:30 +00:00
Kotlin Facet: Configure facet automatically on Gradle project import
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
<pluginDescriptions implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradlePluginDescription"/>
|
||||
</extensions>
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectDataService"/>
|
||||
|
||||
<localInspection
|
||||
implementationClass="org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection"
|
||||
displayName="Kotlin Gradle and IDE plugins versions are different"
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration
|
||||
|
||||
import com.intellij.openapi.externalSystem.model.DataNode
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.idea.facet.configureFacet
|
||||
import org.jetbrains.kotlin.idea.facet.getOrCreateFacet
|
||||
import org.jetbrains.kotlin.idea.inspections.gradle.findAll
|
||||
import org.jetbrains.kotlin.idea.inspections.gradle.findKotlinPluginVersion
|
||||
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData
|
||||
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
|
||||
|
||||
class KotlinGradleProjectDataService : AbstractProjectDataService<GradleSourceSetData, Void>() {
|
||||
override fun getTargetDataKey() = GradleSourceSetData.KEY
|
||||
|
||||
override fun postProcess(
|
||||
toImport: Collection<DataNode<GradleSourceSetData>>,
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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('\\', '/')
|
||||
|
||||
Reference in New Issue
Block a user