From f1463b4a2ea0f0922e523998176f692bd7019484 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 19 Jul 2018 15:03:48 +0300 Subject: [PATCH] Add version replace fix for kotlinx coroutines in Maven (KT-25251) --- .../MavenCoroutinesDeprecationInspection.kt | 70 ++++++++++++--- .../KotlinMavenInspectionTestGenerated.java | 5 ++ .../deprecatedKotlinxCoroutines.fixed.1.xml | 89 +++++++++++++++++++ .../deprecatedKotlinxCoroutinesNoError.xml | 88 ++++++++++++++++++ 4 files changed, 238 insertions(+), 14 deletions(-) create mode 100644 idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutines.fixed.1.xml create mode 100644 idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutinesNoError.xml diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/MavenCoroutinesDeprecationInspection.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/MavenCoroutinesDeprecationInspection.kt index 3f6bc90d671..887e9fee4a1 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/MavenCoroutinesDeprecationInspection.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/MavenCoroutinesDeprecationInspection.kt @@ -6,16 +6,21 @@ package org.jetbrains.kotlin.idea.maven.inspections import com.intellij.codeInspection.CleanupLocalInspectionTool +import com.intellij.codeInspection.LocalQuickFix import com.intellij.codeInspection.ProblemHighlightType import com.intellij.openapi.module.Module import com.intellij.util.xml.DomFileElement import com.intellij.util.xml.highlighting.DomElementAnnotationHolder import com.intellij.util.xml.highlighting.DomElementsInspection +import org.jetbrains.idea.maven.dom.model.MavenDomDependency import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel import org.jetbrains.idea.maven.model.MavenId +import org.jetbrains.idea.maven.project.MavenProjectsManager import org.jetbrains.kotlin.config.LanguageVersion import org.jetbrains.kotlin.idea.configuration.getWholeModuleGroup +import org.jetbrains.kotlin.idea.inspections.ReplaceStringInDocumentFix import org.jetbrains.kotlin.idea.inspections.migration.DEPRECATED_COROUTINES_LIBRARIES_INFORMATION +import org.jetbrains.kotlin.idea.inspections.migration.DeprecatedForKotlinLibInfo import org.jetbrains.kotlin.idea.maven.PomFile import org.jetbrains.kotlin.idea.maven.findDependencies import org.jetbrains.kotlin.idea.project.languageVersionSettings @@ -28,35 +33,72 @@ class MavenCoroutinesDeprecationInspection : val file = domFileElement.file val module = domFileElement.module ?: return + val manager = MavenProjectsManager.getInstance(module.project) ?: return + val mavenProject = manager.findProject(module) ?: return val pomFile = PomFile.forFileOrNull(file) ?: return - for (libInfo in DEPRECATED_COROUTINES_LIBRARIES_INFORMATION) { - if (!checkKotlinVersion(module, libInfo.sinceKotlinLanguageVersion)) { + for (deprecatedLibInfo in DEPRECATED_COROUTINES_LIBRARIES_INFORMATION) { + if (!checkKotlinVersion(module, deprecatedLibInfo.sinceKotlinLanguageVersion)) { // Same result will be for all invocations in this file, so exit return } - val libMavenId = MavenId(libInfo.lib.groupId, libInfo.lib.name, null) + val libMavenId = MavenId(deprecatedLibInfo.lib.groupId, deprecatedLibInfo.lib.name, null) - val moduleDependencies = pomFile.findDependencies(libMavenId) - val dependencyManagementDependencies = pomFile.domModel.dependencyManagement.dependencies.findDependencies(libMavenId) + for (dependency in pomFile.findDependencies(libMavenId)) { + val versionStr = mavenProject.findDependencies(deprecatedLibInfo.lib.groupId, deprecatedLibInfo.lib.name) + .map { it.version } + .distinct() + .singleOrNull() + if (versionStr != null) { + reportDependency(dependency, versionStr, deprecatedLibInfo, holder) + } + } - for (dependency in moduleDependencies + dependencyManagementDependencies) { - val xmlElement = dependency.version.xmlElement - if (xmlElement != null) { - holder.createProblem( - dependency.version, - ProblemHighlightType.GENERIC_ERROR_OR_WARNING, - libInfo.message, - null - ) + for (dependency in pomFile.domModel.dependencyManagement.dependencies.findDependencies(libMavenId)) { + val versionStr = dependency.version?.stringValue + if (versionStr != null) { + reportDependency(dependency, versionStr, deprecatedLibInfo, holder) } } } } companion object { + private fun reportDependency( + dependency: MavenDomDependency, + versionStr: String, + deprecatedLibInfo: DeprecatedForKotlinLibInfo, + holder: DomElementAnnotationHolder + ) { + val updatedVersionStr = deprecatedLibInfo.versionUpdater.updateVersion(versionStr) + if (updatedVersionStr == versionStr) { + return + } + + val xmlElement = dependency.version.xmlElement ?: return + val xmlText = xmlElement.text ?: return + + if (xmlText.contains(updatedVersionStr)) { + return + } + + val fixes: Array = if (xmlText.contains(versionStr)) { + arrayOf(ReplaceStringInDocumentFix(xmlElement, versionStr, updatedVersionStr)) + } else { + emptyArray() + } + + holder.createProblem( + dependency.version, + ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + deprecatedLibInfo.message, + null, + *fixes + ) + } + private fun checkKotlinVersion(module: Module, languageVersion: LanguageVersion): Boolean { val moduleGroup = module.getWholeModuleGroup() return moduleGroup.sourceRootModules.any { moduleInGroup -> diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenInspectionTestGenerated.java b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenInspectionTestGenerated.java index 9f3f54ebfff..dd0adf38b6b 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenInspectionTestGenerated.java +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenInspectionTestGenerated.java @@ -54,6 +54,11 @@ public class KotlinMavenInspectionTestGenerated extends AbstractKotlinMavenInspe runTest("idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutines.xml"); } + @TestMetadata("deprecatedKotlinxCoroutinesNoError.xml") + public void testDeprecatedKotlinxCoroutinesNoError() throws Exception { + runTest("idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutinesNoError.xml"); + } + @TestMetadata("ideAndMavenVersions.xml") public void testIdeAndMavenVersions() throws Exception { runTest("idea/idea-maven/testData/maven-inspections/ideAndMavenVersions.xml"); diff --git a/idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutines.fixed.1.xml b/idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutines.fixed.1.xml new file mode 100644 index 00000000000..01e1877b83c --- /dev/null +++ b/idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutines.fixed.1.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + + maventest + maventest + 1.0-SNAPSHOT + + + 1.2.0 + 1.3 + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk7 + ${kotlin.version} + + + org.jetbrains.kotlinx + kotlinx-coroutines-android + 0.24.0-eap13 + + + + + + + false + + bintray-kotlin-kotlin-eap + bintray + https://dl.bintray.com/kotlin/kotlin-eap + + + + false + + bintray-kotlin-kotlinx + bintray + https://kotlin.bintray.com/kotlinx + + + + + + false + + bintray-kotlin-kotlin-eap + bintray-plugins + https://dl.bintray.com/kotlin/kotlin-eap + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + + + + + \ No newline at end of file diff --git a/idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutinesNoError.xml b/idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutinesNoError.xml new file mode 100644 index 00000000000..0e1448cfaf6 --- /dev/null +++ b/idea/idea-maven/testData/maven-inspections/deprecatedKotlinxCoroutinesNoError.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + maventest + maventest + 1.0-SNAPSHOT + + + 1.2.0 + 1.3 + + + + + org.jetbrains.kotlin + kotlin-stdlib-jdk7 + ${kotlin.version} + + + org.jetbrains.kotlinx + kotlinx-coroutines-android + 0.30.0 + + + + + + + false + + bintray-kotlin-kotlin-eap + bintray + https://dl.bintray.com/kotlin/kotlin-eap + + + + false + + bintray-kotlin-kotlinx + bintray + https://kotlin.bintray.com/kotlinx + + + + + + false + + bintray-kotlin-kotlin-eap + bintray-plugins + https://dl.bintray.com/kotlin/kotlin-eap + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + + + + \ No newline at end of file