Kotlin Facet: Add extension point for compiler/stdlib version info with implementations for Maven and Gradle project models
This commit is contained in:
+38
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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,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()
|
||||
}
|
||||
}
|
||||
+21
-2
@@ -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
|
||||
}
|
||||
}
|
||||
+27
-2
@@ -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')
|
||||
|
||||
+29
-3
@@ -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>()
|
||||
|
||||
|
||||
+11
-8
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user