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
|
||||
|
||||
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.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.psi.psiUtil.getChildrenOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
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.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.blocks.GrClosableBlock
|
||||
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]})"
|
||||
}
|
||||
|
||||
private inner class MyVisitor : BaseInspectionVisitor() {
|
||||
private inner class MyVisitor : KotlinGradleInspectionVisitor() {
|
||||
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) {
|
||||
super.visitClosure(closure)
|
||||
|
||||
@@ -103,9 +74,6 @@ class DifferentKotlinGradleVersionInspection : GradleBaseInspection() {
|
||||
}
|
||||
|
||||
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? {
|
||||
val argumentList = when (classpathStatement) {
|
||||
is GrMethodCall -> classpathStatement.argumentList // classpath('argument')
|
||||
@@ -173,50 +141,5 @@ class DifferentKotlinGradleVersionInspection : GradleBaseInspection() {
|
||||
|
||||
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