Refactoring: extract method for getting Kotlin plugin version and remove findAllRecursively usage
This commit is contained in:
+1
-78
@@ -16,27 +16,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.inspections.gradle
|
package org.jetbrains.kotlin.idea.inspections.gradle
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
|
||||||
import com.intellij.openapi.externalSystem.model.ProjectKeys
|
|
||||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
|
||||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
|
||||||
import com.intellij.openapi.roots.ProjectRootManager
|
|
||||||
import com.intellij.openapi.util.io.FileUtilRt
|
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import com.intellij.util.BooleanFunction
|
|
||||||
import org.jetbrains.annotations.TestOnly
|
import org.jetbrains.annotations.TestOnly
|
||||||
import org.jetbrains.kotlin.idea.KotlinPluginUtil
|
|
||||||
import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator
|
|
||||||
import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID
|
|
||||||
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
|
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
import org.jetbrains.plugins.gradle.codeInspection.GradleBaseInspection
|
import org.jetbrains.plugins.gradle.codeInspection.GradleBaseInspection
|
||||||
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData
|
|
||||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
|
||||||
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection
|
import org.jetbrains.plugins.groovy.codeInspection.BaseInspection
|
||||||
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor
|
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor
|
||||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase
|
|
||||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration
|
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.blocks.GrClosableBlock
|
||||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression
|
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression
|
||||||
@@ -60,24 +46,9 @@ 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]})"
|
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 : BaseInspectionVisitor() {
|
private inner class MyVisitor : KotlinGradleInspectionVisitor() {
|
||||||
private val idePluginVersion by lazy { bundledRuntimeVersion() }
|
private val idePluginVersion by lazy { bundledRuntimeVersion() }
|
||||||
|
|
||||||
override fun visitFile(file: GroovyFileBase?) {
|
|
||||||
if (file == null || !FileUtilRt.extensionEquals(file.name, GradleConstants.EXTENSION)) return
|
|
||||||
|
|
||||||
val fileIndex = ProjectRootManager.getInstance(file.project).fileIndex
|
|
||||||
|
|
||||||
if (!ApplicationManager.getApplication().isUnitTestMode) {
|
|
||||||
val module = fileIndex.getModuleForFile(file.virtualFile) ?: return
|
|
||||||
if (!KotlinPluginUtil.isGradleModule(module)) return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileIndex.isExcluded(file.virtualFile)) return
|
|
||||||
|
|
||||||
super.visitFile(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitClosure(closure: GrClosableBlock) {
|
override fun visitClosure(closure: GrClosableBlock) {
|
||||||
super.visitClosure(closure)
|
super.visitClosure(closure)
|
||||||
|
|
||||||
@@ -103,9 +74,6 @@ class DifferentKotlinGradleVersionInspection : GradleBaseInspection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val KOTLIN_PLUGIN_CLASSPATH_MARKER = "${KotlinWithGradleConfigurator.GROUP_ID}:${KotlinWithGradleConfigurator.GRADLE_PLUGIN_ID}:"
|
|
||||||
val KOTLIN_PLUGIN_PATH_MARKER = "${KotlinWithGradleConfigurator.GROUP_ID}/${KotlinWithGradleConfigurator.GRADLE_PLUGIN_ID}/"
|
|
||||||
|
|
||||||
private fun getHeuristicKotlinPluginVersion(classpathStatement: GrCallExpression): String? {
|
private fun getHeuristicKotlinPluginVersion(classpathStatement: GrCallExpression): String? {
|
||||||
val argumentList = when (classpathStatement) {
|
val argumentList = when (classpathStatement) {
|
||||||
is GrMethodCall -> classpathStatement.argumentList // classpath('argument')
|
is GrMethodCall -> classpathStatement.argumentList // classpath('argument')
|
||||||
@@ -173,50 +141,5 @@ class DifferentKotlinGradleVersionInspection : GradleBaseInspection() {
|
|||||||
|
|
||||||
return classPathStatements
|
return classPathStatements
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getResolvedKotlinGradleVersion(file: PsiFile): String? {
|
|
||||||
val project = file.project
|
|
||||||
val module = ProjectRootManager.getInstance(file.project).fileIndex.getModuleForFile(file.virtualFile) ?: return null
|
|
||||||
val projectPath = project.basePath ?: return null
|
|
||||||
|
|
||||||
val projectInfo = ExternalSystemUtil.getExternalProjectInfo(project, GRADLE_SYSTEM_ID, projectPath) ?: return null
|
|
||||||
val externalProjectStructure = projectInfo.externalProjectStructure ?: return null
|
|
||||||
|
|
||||||
val buildScriptClasspathDataNodes = ExternalSystemApiUtil.findAllRecursively(externalProjectStructure, BooleanFunction { node ->
|
|
||||||
BuildScriptClasspathData.KEY == node.key
|
|
||||||
})
|
|
||||||
|
|
||||||
for (buildScriptClasspathDataNode in buildScriptClasspathDataNodes) {
|
|
||||||
val moduleNode = buildScriptClasspathDataNode.parent
|
|
||||||
val moduleData = moduleNode?.getData(ProjectKeys.MODULE)
|
|
||||||
if (moduleData?.internalName == module.name) {
|
|
||||||
val buildScriptClasspathData = buildScriptClasspathDataNode.getData(BuildScriptClasspathData.KEY)
|
|
||||||
if (buildScriptClasspathData != null) {
|
|
||||||
val kotlinPluginVersion = findKotlinPluginVersion(buildScriptClasspathData)
|
|
||||||
if (kotlinPluginVersion != null) {
|
|
||||||
return kotlinPluginVersion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): String? {
|
|
||||||
for (classPathEntry in classpathData.classpathEntries) {
|
|
||||||
for (path in classPathEntry.classesFile) {
|
|
||||||
val uniformedPath = path.replace('\\', '/')
|
|
||||||
if (uniformedPath.contains(KOTLIN_PLUGIN_PATH_MARKER)) {
|
|
||||||
val versionSubstring = uniformedPath.substringAfter(KOTLIN_PLUGIN_PATH_MARKER).substringBefore('/', "<error>")
|
|
||||||
if (versionSubstring != "<error>") {
|
|
||||||
return versionSubstring;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+100
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* 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.inspections.gradle
|
||||||
|
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.externalSystem.model.DataNode
|
||||||
|
import com.intellij.openapi.externalSystem.model.Key
|
||||||
|
import com.intellij.openapi.externalSystem.model.ProjectKeys
|
||||||
|
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||||
|
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||||
|
import com.intellij.openapi.roots.ProjectRootManager
|
||||||
|
import com.intellij.openapi.util.io.FileUtilRt
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinPluginUtil
|
||||||
|
import org.jetbrains.kotlin.idea.configuration.KotlinWithGradleConfigurator
|
||||||
|
import org.jetbrains.kotlin.idea.framework.GRADLE_SYSTEM_ID
|
||||||
|
import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData
|
||||||
|
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||||
|
import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor
|
||||||
|
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase
|
||||||
|
|
||||||
|
val KOTLIN_PLUGIN_CLASSPATH_MARKER = "${KotlinWithGradleConfigurator.GROUP_ID}:${KotlinWithGradleConfigurator.GRADLE_PLUGIN_ID}:"
|
||||||
|
val KOTLIN_PLUGIN_PATH_MARKER = "${KotlinWithGradleConfigurator.GROUP_ID}/${KotlinWithGradleConfigurator.GRADLE_PLUGIN_ID}/"
|
||||||
|
|
||||||
|
abstract class KotlinGradleInspectionVisitor : BaseInspectionVisitor() {
|
||||||
|
override fun visitFile(file: GroovyFileBase?) {
|
||||||
|
if (file == null || !FileUtilRt.extensionEquals(file.name, GradleConstants.EXTENSION)) return
|
||||||
|
|
||||||
|
val fileIndex = ProjectRootManager.getInstance(file.project).fileIndex
|
||||||
|
|
||||||
|
if (!ApplicationManager.getApplication().isUnitTestMode) {
|
||||||
|
val module = fileIndex.getModuleForFile(file.virtualFile) ?: return
|
||||||
|
if (!KotlinPluginUtil.isGradleModule(module)) return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileIndex.isExcluded(file.virtualFile)) return
|
||||||
|
|
||||||
|
super.visitFile(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getResolvedKotlinGradleVersion(file: PsiFile): String? {
|
||||||
|
val project = file.project
|
||||||
|
val module = ProjectRootManager.getInstance(file.project).fileIndex.getModuleForFile(file.virtualFile) ?: return null
|
||||||
|
val projectPath = project.basePath ?: return null
|
||||||
|
|
||||||
|
val projectInfo = ExternalSystemUtil.getExternalProjectInfo(project, GRADLE_SYSTEM_ID, projectPath) ?: return null
|
||||||
|
val projectStructureNode = projectInfo.externalProjectStructure ?: 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)
|
||||||
|
if (kotlinPluginVersion != null) {
|
||||||
|
return kotlinPluginVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findKotlinPluginVersion(classpathData: BuildScriptClasspathData): String? {
|
||||||
|
for (classPathEntry in classpathData.classpathEntries) {
|
||||||
|
for (path in classPathEntry.classesFile) {
|
||||||
|
val uniformedPath = path.replace('\\', '/')
|
||||||
|
if (uniformedPath.contains(KOTLIN_PLUGIN_PATH_MARKER)) {
|
||||||
|
val versionSubstring = uniformedPath.substringAfter(KOTLIN_PLUGIN_PATH_MARKER).substringBefore('/', "<error>")
|
||||||
|
if (versionSubstring != "<error>") {
|
||||||
|
return versionSubstring;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
class NodeWithData<T>(val node: DataNode<*>, val data: T)
|
||||||
|
|
||||||
|
fun <T: Any> DataNode<*>.findAll(key: Key<T>): List<NodeWithData<T>> {
|
||||||
|
val nodes = ExternalSystemApiUtil.findAll(this, key)
|
||||||
|
return nodes.mapNotNull {
|
||||||
|
val data = it.getData(key) ?: return@mapNotNull null
|
||||||
|
NodeWithData(it, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user