Kotlin Facet: Add extension point for compiler/stdlib version info with implementations for Maven and Gradle project models

This commit is contained in:
Alexey Sedunov
2016-10-14 19:44:53 +03:00
parent e0285b9955
commit 03f4d9f574
12 changed files with 259 additions and 48 deletions
@@ -0,0 +1,38 @@
/*
* 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.maven.facet
import com.intellij.openapi.module.Module
import org.jetbrains.idea.maven.project.MavenProjectsManager
import org.jetbrains.kotlin.idea.facet.KotlinFacetConfiguration
import org.jetbrains.kotlin.idea.facet.KotlinVersionInfoProvider
import org.jetbrains.kotlin.idea.facet.mavenLibraryId
import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator
class MavenKotlinVersionInfoProvider : KotlinVersionInfoProvider {
override fun getCompilerVersion(module: Module): String? {
val projectsManager = MavenProjectsManager.getInstance(module.project)
val mavenProject = projectsManager.findProject(module) ?: return null
return mavenProject.findPlugin(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID)?.version
}
override fun getLibraryVersions(module: Module, targetPlatform: KotlinFacetConfiguration.TargetPlatform): 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()
}
}
+2
View File
@@ -36,5 +36,7 @@
area="IDEA_PROJECT"/>
<extensionPoint name="facetConfigurationExtension"
interface="org.jetbrains.kotlin.idea.facet.KotlinFacetConfigurationExtension"/>
<extensionPoint name="versionInfoProvider"
interface="org.jetbrains.kotlin.idea.facet.KotlinVersionInfoProvider"/>
</extensionPoints>
</idea-plugin>
+2
View File
@@ -1,6 +1,8 @@
<idea-plugin>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleModuleConfigurator"/>
<versionInfoProvider implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinVersionInfoProvider"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
+2
View File
@@ -2,6 +2,8 @@
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<projectConfigurator implementation="org.jetbrains.kotlin.idea.maven.configuration.KotlinJavaMavenConfigurator"/>
<projectConfigurator implementation="org.jetbrains.kotlin.idea.maven.configuration.KotlinJavascriptMavenConfigurator"/>
<versionInfoProvider implementation="org.jetbrains.kotlin.idea.maven.facet.MavenKotlinVersionInfoProvider"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.idea.maven">
<importer implementation="org.jetbrains.kotlin.idea.maven.KotlinMavenImporter" />
@@ -0,0 +1,51 @@
/*
* 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.util.ExternalSystemApiUtil
import com.intellij.openapi.module.Module
import org.jetbrains.kotlin.idea.facet.KotlinFacetConfiguration
import org.jetbrains.kotlin.idea.facet.KotlinVersionInfoProvider
import org.jetbrains.kotlin.idea.facet.mavenLibraryId
import org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection
import org.jetbrains.kotlin.idea.inspections.gradle.DifferentStdlibGradleVersionInspection
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
import org.jetbrains.kotlin.idea.refactoring.toVirtualFile
import org.jetbrains.plugins.gradle.service.project.data.ExternalProjectDataCache
import org.jetbrains.plugins.gradle.util.GradleConstants
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase
import java.io.File
class GradleKotlinVersionInfoProvider : KotlinVersionInfoProvider {
private fun getGradleFile(module: Module): GroovyFileBase? {
val rootDir = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null
val externalProjectDataCache = ExternalProjectDataCache.getInstance(module.project)
val rootProject = externalProjectDataCache.getRootExternalProject(GradleConstants.SYSTEM_ID, File(rootDir)) ?: return null
val buildFile = rootProject.buildFile ?: return null
return buildFile.toVirtualFile()?.toPsiFile(module.project) as? GroovyFileBase ?: return null
}
override fun getCompilerVersion(module: Module): String? {
return getGradleFile(module)?.let { DifferentKotlinGradleVersionInspection.getKotlinPluginVersion(it) }
}
override fun getLibraryVersions(module: Module, targetPlatform: KotlinFacetConfiguration.TargetPlatform): Collection<String> {
return getGradleFile(module)?.let {
DifferentStdlibGradleVersionInspection.getKotlinStdlibVersions(it, targetPlatform.mavenLibraryId)
} ?: emptyList()
}
}
@@ -25,6 +25,8 @@ import com.intellij.ide.IdeBundle
import com.intellij.openapi.roots.ui.configuration.libraries.AddCustomLibraryDialog
import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription
import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager
import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription
import org.jetbrains.kotlin.idea.framework.JavaRuntimeLibraryDescription
import javax.swing.JComponent
// Based on com.intellij.facet.impl.ui.libraries.FrameworkLibraryValidatorImpl
@@ -32,10 +34,27 @@ class FrameworkLibraryValidatorWithDynamicDescription(
private val context: LibrariesValidatorContext,
private val validatorsManager: FacetValidatorsManager,
private val libraryCategoryName: String,
private val getLibraryDescription: () -> CustomLibraryDescription
private val getTargetPlatform: () -> KotlinFacetConfiguration.TargetPlatform
) : FrameworkLibraryValidator() {
private val KotlinFacetConfiguration.TargetPlatform.libraryDescription: CustomLibraryDescription
get() {
val project = context.module.project
return when (this) {
KotlinFacetConfiguration.TargetPlatform.JVM_1_6, KotlinFacetConfiguration.TargetPlatform.JVM_1_8 ->
JavaRuntimeLibraryDescription(project)
KotlinFacetConfiguration.TargetPlatform.JS ->
JSLibraryStdDescription(project)
}
}
override fun check(): ValidationResult {
val libraryDescription = getLibraryDescription()
val targetPlatform = getTargetPlatform()
if (KotlinVersionInfoProvider.EP_NAME.extensions.any { it.getLibraryVersions(context.module, targetPlatform).isNotEmpty() }) {
return ValidationResult.OK
}
val libraryDescription = targetPlatform.libraryDescription
val libraryKinds = libraryDescription.suitableLibraryKinds
var found = false
val presentationManager = LibraryPresentationManager.getInstance()
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.idea.facet
import com.intellij.facet.impl.ui.libraries.DelegatingLibrariesValidatorContext
import com.intellij.facet.ui.*
import com.intellij.facet.ui.libraries.FrameworkLibraryValidator
import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription
import com.intellij.util.ui.FormBuilder
import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription
import org.jetbrains.kotlin.idea.framework.JavaRuntimeLibraryDescription
import org.jetbrains.kotlin.idea.util.DescriptionAware
import java.awt.BorderLayout
import java.awt.Component
@@ -54,15 +51,7 @@ class KotlinFacetEditorTab(
}
}
private val KotlinFacetConfiguration.TargetPlatform.libraryDescription: CustomLibraryDescription
get() {
return when (this) {
KotlinFacetConfiguration.TargetPlatform.JVM_1_6, KotlinFacetConfiguration.TargetPlatform.JVM_1_8 ->
JavaRuntimeLibraryDescription(editorContext.project)
KotlinFacetConfiguration.TargetPlatform.JS ->
JSLibraryStdDescription(editorContext.project)
}
}
private val languageVersionComboBox =
JComboBox<KotlinFacetConfiguration.LanguageLevel>(KotlinFacetConfiguration.LanguageLevel.values()).apply {
@@ -87,7 +76,7 @@ class KotlinFacetEditorTab(
DelegatingLibrariesValidatorContext(editorContext),
validatorsManager,
"kotlin"
) { (targetPlatformComboBox.selectedItem as KotlinFacetConfiguration.TargetPlatform).libraryDescription }
) { targetPlatformComboBox.selectedItem as KotlinFacetConfiguration.TargetPlatform }
validatorsManager.registerValidator(libraryValidator)
validatorsManager.registerValidator(versionValidator)
@@ -0,0 +1,29 @@
/*
* 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.facet
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.module.Module
interface KotlinVersionInfoProvider {
companion object {
val EP_NAME: ExtensionPointName<KotlinVersionInfoProvider> = ExtensionPointName.create("org.jetbrains.kotlin.versionInfoProvider")!!
}
fun getCompilerVersion(module: Module): String?
fun getLibraryVersions(module: Module, targetPlatform: KotlinFacetConfiguration.TargetPlatform): Collection<String>
}
@@ -16,25 +16,39 @@
package org.jetbrains.kotlin.idea.facet
import com.intellij.framework.library.LibraryVersionProperties
import com.intellij.openapi.module.Module
import com.intellij.openapi.projectRoots.JavaSdk
import com.intellij.openapi.projectRoots.JavaSdkVersion
import com.intellij.openapi.roots.LibraryOrderEntry
import com.intellij.openapi.roots.ModuleRootManager
import com.intellij.openapi.roots.ModuleRootModel
import com.intellij.openapi.roots.libraries.LibraryPresentationProvider
import com.intellij.util.text.VersionComparatorUtil
import org.jetbrains.kotlin.idea.framework.JSLibraryStdPresentationProvider
import org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider
import org.jetbrains.kotlin.idea.framework.getLibraryProperties
import org.jetbrains.kotlin.idea.maven.configuration.KotlinJavaMavenConfigurator
import org.jetbrains.kotlin.idea.maven.configuration.KotlinJavascriptMavenConfigurator
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
private fun getRuntimeLibraryVersions(
module: Module,
rootModel: ModuleRootModel?,
presentationProvider: LibraryPresentationProvider<LibraryVersionProperties>
): List<String> {
targetPlatform: KotlinFacetConfiguration.TargetPlatform
): Collection<String> {
val presentationProvider = when (targetPlatform) {
KotlinFacetConfiguration.TargetPlatform.JS ->
JSLibraryStdPresentationProvider.getInstance()
KotlinFacetConfiguration.TargetPlatform.JVM_1_6,
KotlinFacetConfiguration.TargetPlatform.JVM_1_8 ->
JavaRuntimePresentationProvider.getInstance()
}
KotlinVersionInfoProvider.EP_NAME
.extensions
.map { it.getLibraryVersions(module, targetPlatform) }
.firstOrNull { it.isNotEmpty() }
?.let { return it }
return (rootModel ?: ModuleRootManager.getInstance(module))
.orderEntries
.asSequence()
@@ -44,9 +58,9 @@ private fun getRuntimeLibraryVersions(
}
private fun getDefaultTargetPlatform(module: Module, rootModel: ModuleRootModel?): KotlinFacetConfiguration.TargetPlatform {
getRuntimeLibraryVersions(module, rootModel, JSLibraryStdPresentationProvider.getInstance())
.firstOrNull()
?.let { return KotlinFacetConfiguration.TargetPlatform.JS }
if (getRuntimeLibraryVersions(module, rootModel, KotlinFacetConfiguration.TargetPlatform.JS).any()) {
return KotlinFacetConfiguration.TargetPlatform.JS
}
val sdk = ((rootModel ?: ModuleRootManager.getInstance(module))).sdk
val sdkVersion = (sdk?.sdkType as? JavaSdk)?.getVersion(sdk!!)
@@ -56,8 +70,15 @@ private fun getDefaultTargetPlatform(module: Module, rootModel: ModuleRootModel?
}
}
private fun getDefaultLanguageLevel(explicitVersion: String? = null): KotlinFacetConfiguration.LanguageLevel {
val libVersion = explicitVersion ?: bundledRuntimeVersion()
private fun getDefaultLanguageLevel(
module: Module,
explicitVersion: String? = null
): KotlinFacetConfiguration.LanguageLevel {
val libVersion = explicitVersion
?: KotlinVersionInfoProvider.EP_NAME.extensions
.mapNotNull { it.getCompilerVersion(module) }
.minWith(VersionComparatorUtil.COMPARATOR)
?: bundledRuntimeVersion()
return when {
libVersion.startsWith("1.0") -> KotlinFacetConfiguration.LanguageLevel.KOTLIN_1_0
else -> KotlinFacetConfiguration.LanguageLevel.KOTLIN_1_1
@@ -69,16 +90,9 @@ internal fun getLibraryLanguageLevel(
rootModel: ModuleRootModel?,
targetPlatform: KotlinFacetConfiguration.TargetPlatform?
): KotlinFacetConfiguration.LanguageLevel {
val presentationProvider = when (targetPlatform) {
KotlinFacetConfiguration.TargetPlatform.JS ->
JSLibraryStdPresentationProvider.getInstance()
KotlinFacetConfiguration.TargetPlatform.JVM_1_6,
KotlinFacetConfiguration.TargetPlatform.JVM_1_8,
null ->
JavaRuntimePresentationProvider.getInstance()
}
val minVersion = getRuntimeLibraryVersions(module, rootModel, presentationProvider).minWith(VersionComparatorUtil.COMPARATOR)
return getDefaultLanguageLevel(minVersion)
val minVersion = getRuntimeLibraryVersions(module, rootModel, targetPlatform ?: KotlinFacetConfiguration.TargetPlatform.JVM_1_8)
.minWith(VersionComparatorUtil.COMPARATOR)
return getDefaultLanguageLevel(module, minVersion)
}
internal fun KotlinFacetConfiguration.VersionInfo.initializeIfNeeded(module: Module, rootModel: ModuleRootModel?) {
@@ -87,7 +101,7 @@ internal fun KotlinFacetConfiguration.VersionInfo.initializeIfNeeded(module: Mod
}
if (languageLevel == null) {
languageLevel = getDefaultLanguageLevel()
languageLevel = getDefaultLanguageLevel(module)
}
if (apiLevel == null) {
@@ -100,3 +114,14 @@ internal fun Module.getKotlinVersionInfo(rootModel: ModuleRootModel? = null): Ko
versionInfo.initializeIfNeeded(this, rootModel)
return versionInfo
}
val KotlinFacetConfiguration.TargetPlatform.mavenLibraryId: String
get() {
return when (this) {
KotlinFacetConfiguration.TargetPlatform.JVM_1_6,
KotlinFacetConfiguration.TargetPlatform.JVM_1_8 ->
KotlinJavaMavenConfigurator.STD_LIB_ID
KotlinFacetConfiguration.TargetPlatform.JS ->
KotlinJavascriptMavenConfigurator.STD_LIB_ID
}
}
@@ -23,6 +23,8 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.plugins.gradle.codeInspection.GradleBaseInspection
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression
@@ -46,8 +48,8 @@ class DifferentKotlinGradleVersionInspection : GradleBaseInspection() {
return "Kotlin version that is used for building with Gradle (${args[0]}) differs from the one bundled into the IDE plugin (${args[1]})"
}
private inner class MyVisitor : KotlinGradleInspectionVisitor() {
private val idePluginVersion by lazy { bundledRuntimeVersion() }
private abstract class VersionFinder : KotlinGradleInspectionVisitor() {
protected abstract fun onFound(kotlinPluginVersion: String, kotlinPluginStatement: GrCallExpression)
override fun visitClosure(closure: GrClosableBlock) {
super.visitClosure(closure)
@@ -67,6 +69,14 @@ class DifferentKotlinGradleVersionInspection : GradleBaseInspection() {
getResolvedKotlinGradleVersion(closure.containingFile) ?:
return
onFound(kotlinPluginVersion, kotlinPluginStatement)
}
}
private inner class MyVisitor: VersionFinder() {
private val idePluginVersion by lazy { bundledRuntimeVersion() }
override fun onFound(kotlinPluginVersion: String, kotlinPluginStatement: GrCallExpression) {
if (kotlinPluginVersion != idePluginVersion) {
registerError(kotlinPluginStatement, kotlinPluginVersion, testVersionMessage ?: idePluginVersion)
}
@@ -74,6 +84,21 @@ class DifferentKotlinGradleVersionInspection : GradleBaseInspection() {
}
companion object {
fun getKotlinPluginVersion(gradleFile: GroovyFileBase): String? {
var version: String? = null
val visitor = object : VersionFinder() {
override fun visitElement(element: GroovyPsiElement) {
element.acceptChildren(this)
}
override fun onFound(kotlinPluginVersion: String, kotlinPluginStatement: GrCallExpression) {
version = kotlinPluginVersion
}
}
gradleFile.accept(visitor)
return version
}
private fun getHeuristicKotlinPluginVersion(classpathStatement: GrCallExpression): String? {
val argumentList = when (classpathStatement) {
is GrMethodCall -> classpathStatement.argumentList // classpath('argument')
@@ -24,18 +24,23 @@ import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.plugins.gradle.codeInspection.GradleBaseInspection
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression
import java.util.*
class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
override fun buildVisitor(): BaseInspectionVisitor = MyVisitor()
override fun buildVisitor(): BaseInspectionVisitor = MyVisitor("kotlin-stdlib")
override fun buildErrorString(vararg args: Any) =
"Plugin version (${args[0]}) is not the same as library version (${args[1]})"
private inner class MyVisitor : KotlinGradleInspectionVisitor() {
private abstract class VersionFinder(private val libraryId: String) : KotlinGradleInspectionVisitor() {
protected abstract fun onFound(stdlibVersion: String, stdlibStatement: GrCallExpression)
override fun visitClosure(closure: GrClosableBlock) {
super.visitClosure(closure)
@@ -47,7 +52,13 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
val stdlibStatement = findLibraryStatement(closure, "org.jetbrains.kotlin", "kotlin-stdlib") ?: return
val stdlibVersion = getResolvedKotlinStdlibVersion(closure.containingFile, "org.jetbrains.kotlin:kotlin-stdlib:") ?: return
val gradlePluginVersion = getResolvedKotlinGradleVersion(closure.containingFile)
onFound(stdlibVersion, stdlibStatement)
}
}
private inner class MyVisitor(libraryId: String): VersionFinder(libraryId) {
override fun onFound(stdlibVersion: String, stdlibStatement: GrCallExpression) {
val gradlePluginVersion = getResolvedKotlinGradleVersion(stdlibStatement.containingFile)
if (stdlibVersion != gradlePluginVersion) {
registerError(stdlibStatement, gradlePluginVersion, stdlibVersion)
@@ -58,6 +69,21 @@ class DifferentStdlibGradleVersionInspection : GradleBaseInspection() {
companion object {
val COMPILE_DEPENDENCY_STATEMENTS = listOf("classpath", "compile")
fun getKotlinStdlibVersions(gradleFile: GroovyFileBase, libraryId: String): Collection<String> {
val versions = LinkedHashSet<String>()
val visitor = object : VersionFinder(libraryId) {
override fun visitElement(element: GroovyPsiElement) {
element.acceptChildren(this)
}
override fun onFound(stdlibVersion: String, stdlibStatement: GrCallExpression) {
versions += stdlibVersion
}
}
gradleFile.accept(visitor)
return versions
}
private fun findLibraryStatement(closure: GrClosableBlock, libraryGroup: String, libraryId: String): GrCallExpression? {
val applicationStatements = closure.getChildrenOfType<GrCallExpression>()
@@ -23,6 +23,8 @@ import com.intellij.openapi.externalSystem.model.ProjectKeys
import com.intellij.openapi.externalSystem.model.project.ProjectData
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.psi.PsiFile
@@ -54,10 +56,11 @@ abstract class KotlinGradleInspectionVisitor : BaseInspectionVisitor() {
}
}
fun getResolvedKotlinGradleVersion(file: PsiFile): String? {
val module = ProjectRootManager.getInstance(file.project).fileIndex.getModuleForFile(file.virtualFile) ?: return null
val projectStructureNode = findGradleProjectStructure(file) ?: return null
fun getResolvedKotlinGradleVersion(file: PsiFile) =
ModuleUtilCore.findModuleForFile(file.virtualFile, file.project)?.let { getResolvedKotlinGradleVersion(it) }
fun getResolvedKotlinGradleVersion(module: Module): String? {
val projectStructureNode = findGradleProjectStructure(module) ?: return null
for (moduleData in projectStructureNode.findAll(ProjectKeys.MODULE).filter { it.data.internalName == module.name }) {
val buildScriptClasspathData = moduleData.node.findAll(BuildScriptClasspathData.KEY).firstOrNull()?.data ?: continue
val kotlinPluginVersion = findKotlinPluginVersion(buildScriptClasspathData)
@@ -95,11 +98,11 @@ fun <T: Any> DataNode<*>.findAll(key: Key<T>): List<NodeWithData<T>> {
}
}
fun findGradleProjectStructure(file: PsiFile): DataNode<ProjectData>? {
val project = file.project
val module = ProjectRootManager.getInstance(project).fileIndex.getModuleForFile(file.virtualFile) ?: return null
val externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null
fun findGradleProjectStructure(file: PsiFile) =
ModuleUtilCore.findModuleForFile(file.virtualFile, file.project)?.let { findGradleProjectStructure(it) }
val projectInfo = ExternalSystemUtil.getExternalProjectInfo(project, GRADLE_SYSTEM_ID, externalProjectPath) ?: return null
fun findGradleProjectStructure(module: Module): DataNode<ProjectData>? {
val externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null
val projectInfo = ExternalSystemUtil.getExternalProjectInfo(module.project, GRADLE_SYSTEM_ID, externalProjectPath) ?: return null
return projectInfo.externalProjectStructure
}