From 2637a36e221ed827c752269b28628150564cfe55 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 17 Jan 2018 16:56:16 +0300 Subject: [PATCH] Inspection doesn't suggest Maven Plugin for kotlin-stdlib-jre8 (KT-18007) #KT-18007 Fixed --- .../jetbrains/kotlin/idea/maven/PomFile.kt | 11 ++++- .../KotlinMavenPluginPhaseInspection.kt | 19 +++++--- .../AbstractKotlinMavenInspectionTest.kt | 45 ++++++++++++++++--- ...> dependencyWithNoExecution.fixed.1-5.xml} | 24 ++++++++++ ... => dependencyWithNoExecution.fixed.6.xml} | 24 ++++++++++ .../dependencyWithNoExecution.xml | 24 ++++++++++ 6 files changed, 134 insertions(+), 13 deletions(-) rename idea/idea-maven/testData/maven-inspections/{dependencyWithNoExecution.fixed.1.xml => dependencyWithNoExecution.fixed.1-5.xml} (58%) rename idea/idea-maven/testData/maven-inspections/{dependencyWithNoExecution.fixed.2.xml => dependencyWithNoExecution.fixed.6.xml} (58%) diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt index f4f14837554..8f8ff7972ae 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/PomFile.kt @@ -42,6 +42,7 @@ import org.jetbrains.jps.model.java.JavaSourceRootType import org.jetbrains.kotlin.idea.configuration.RepositoryDescription import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType +import org.jetbrains.kotlin.utils.SmartList import java.util.* fun kotlinPluginId(version: String?) = MavenId(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID, version) @@ -415,7 +416,15 @@ class PomFile private constructor(private val xmlFile: XmlFile, val domModel: Ma } fun findDependencies(artifact: MavenId, scope: MavenArtifactScope? = null) = - domModel.dependencies.dependencies.filter { it.matches(artifact, scope) } + findDependencies(SmartList(artifact), scope) + + fun findDependencies(artifacts: List, scope: MavenArtifactScope? = null): List { + return domModel.dependencies.dependencies.filter { dependency -> + artifacts.any { artifact -> + dependency.matches(artifact, scope) + } + } + } private fun ensureBuild(): XmlTag = ensureElement(projectElement, "build") diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/KotlinMavenPluginPhaseInspection.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/KotlinMavenPluginPhaseInspection.kt index 87b12f4ba0b..49c9140b75d 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/KotlinMavenPluginPhaseInspection.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/inspections/KotlinMavenPluginPhaseInspection.kt @@ -38,11 +38,20 @@ import org.jetbrains.idea.maven.project.MavenProjectsManager import org.jetbrains.idea.maven.utils.MavenArtifactScope import org.jetbrains.kotlin.idea.maven.PomFile import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator -import org.jetbrains.kotlin.idea.versions.MAVEN_JS_STDLIB_ID -import org.jetbrains.kotlin.idea.versions.MAVEN_STDLIB_ID +import org.jetbrains.kotlin.idea.versions.* import java.util.* class KotlinMavenPluginPhaseInspection : DomElementsInspection(MavenDomProjectModel::class.java) { + companion object { + private val STDLIB_MAVEN_ID = MavenId(KotlinMavenConfigurator.GROUP_ID, MAVEN_STDLIB_ID, null) + private val STDLIB_JRE7_MAVEN_ID = MavenId(KotlinMavenConfigurator.GROUP_ID, MAVEN_STDLIB_ID_JRE7, null) + private val STDLIB_JDK7_MAVEN_ID = MavenId(KotlinMavenConfigurator.GROUP_ID, MAVEN_STDLIB_ID_JDK7, null) + private val STDLIB_JRE8_MAVEN_ID = MavenId(KotlinMavenConfigurator.GROUP_ID, MAVEN_STDLIB_ID_JRE8, null) + private val STDLIB_JDK8_MAVEN_ID = MavenId(KotlinMavenConfigurator.GROUP_ID, MAVEN_STDLIB_ID_JDK8, null) + + private val JVM_STDLIB_IDS = listOf(STDLIB_MAVEN_ID, STDLIB_JRE7_MAVEN_ID, STDLIB_JDK7_MAVEN_ID, STDLIB_JRE8_MAVEN_ID, STDLIB_JDK8_MAVEN_ID) + } + override fun getStaticDescription() = "Reports kotlin-maven-plugin configuration issues" override fun checkFileElement(domFileElement: DomFileElement?, holder: DomElementAnnotationHolder?) { @@ -142,9 +151,9 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection + val jvmStdlibDependencies = pom.findDependencies(JVM_STDLIB_IDS) + if (!hasJvmExecution && jvmStdlibDependencies.isNotEmpty()) { + jvmStdlibDependencies.forEach { dep -> holder.createProblem( dep.artifactId.createStableCopy(), HighlightSeverity.WARNING, diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt index aee372b1f74..17fe0277790 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/AbstractKotlinMavenInspectionTest.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.idea.maven.inspections.KotlinMavenPluginPhaseInspect import org.jetbrains.kotlin.idea.refactoring.toPsiDirectory import org.jetbrains.kotlin.idea.util.projectStructure.allModules import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.utils.keysToMap import java.io.File abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() { @@ -64,8 +65,10 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() { val inspectionClass = Class.forName(inspectionClassName) val matcher = "".toRegex() - val expected = pomText.lines().mapNotNull { matcher.find(it) } - .map { SimplifiedProblemDescription(it.groups[2]!!.value.trim(), it.groups[1]!!.value.trim()) } + val expectedProblemsText = pomText.lines() + .filter { matcher.matches(it) } + .joinToString("\n") + val problemElements = runInspection(inspectionClass, myProject).problemElements val actualProblems = problemElements .keys() @@ -78,7 +81,11 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() { .map { SimplifiedProblemDescription(it.descriptionTemplate, it.psiElement.text.replace("\\s+".toRegex(), "")) to it } .sortedBy { it.first.text } - assertEquals(expected.sortedBy { it.text }, actual.map { it.first }) + val actualProblemsText = actual + .map { it.first } + .joinToString("\n") { ""} + + assertEquals(expectedProblemsText, actualProblemsText) val suggestedFixes = actual.flatMap { p -> p.second.fixes?.sortedBy { it.familyName }?.map { p.second to it } ?: emptyList() } @@ -86,10 +93,33 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() { val fixFiles = pomFile.parentFile.listFiles { _, name -> name.startsWith(filenamePrefix) && name.endsWith(".xml") }.sortedBy { it.name } - if (fixFiles.size > suggestedFixes.size) { + val rangesToFixFiles: Map = fixFiles.keysToMap { + val fixFileName = it.name + val fixRangeStr = fixFileName.substringBeforeLast('.').substringAfterLast('.') + val numbers = fixRangeStr.split('-').map { it.toInt() } + when (numbers.size) { + 0 -> error("No number in fix file $fixFileName") + 1 -> IntRange(numbers[0], numbers[0]) + 2 -> IntRange(numbers[0], numbers[1]) + else -> error("Bad range `$fixRangeStr` in fix file $fixFileName") + } + } + + val sortedFixRanges = rangesToFixFiles.values.sortedBy { it.start } + sortedFixRanges.forEachIndexed { i, range -> + if (i > 0) { + val previous = sortedFixRanges[i - 1] + if (previous.endInclusive + 1 != range.start) { + error("Bad ranges in fix files: $previous and $range") + } + } + } + + val numberOfFixDataFiles = sortedFixRanges.lastOrNull()?.endInclusive ?: 0 + if (numberOfFixDataFiles > suggestedFixes.size) { fail("Not all fixes were suggested by the inspection: expected count: ${fixFiles.size}, actual fixes count: ${suggestedFixes.size}") } - if (fixFiles.size < suggestedFixes.size) { + if (numberOfFixDataFiles < suggestedFixes.size) { fail("Not all fixes covered by *.fixed.N.xml files") } @@ -97,8 +127,9 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() { val document = documentManager.getDocument(PsiManager.getInstance(myProject).findFile(myProjectPom)!!)!! val originalText = document.text - fixFiles.forEachIndexed { index, file -> - val (problem, quickfix) = suggestedFixes[index] + suggestedFixes.forEachIndexed { index, suggestedFix -> + val (problem, quickfix) = suggestedFix + val file = rangesToFixFiles.entries.first { (_, range) -> index + 1 in range }.key quickfix.applyFix(problem) diff --git a/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.1.xml b/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.1-5.xml similarity index 58% rename from idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.1.xml rename to idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.1-5.xml index 5cb4cae548e..3c069144920 100644 --- a/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.1.xml +++ b/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.1-5.xml @@ -18,6 +18,26 @@ kotlin-stdlib ${kotlin.version} + + org.jetbrains.kotlin + kotlin-stdlib-jre7 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jre8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jdk7 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + org.jetbrains.kotlin kotlin-stdlib-js @@ -48,4 +68,8 @@ + + + + diff --git a/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.2.xml b/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.6.xml similarity index 58% rename from idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.2.xml rename to idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.6.xml index 8f6d1b6af9f..d120652f710 100644 --- a/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.2.xml +++ b/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.fixed.6.xml @@ -18,6 +18,26 @@ kotlin-stdlib ${kotlin.version} + + org.jetbrains.kotlin + kotlin-stdlib-jre7 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jre8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jdk7 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + org.jetbrains.kotlin kotlin-stdlib-js @@ -48,4 +68,8 @@ + + + + diff --git a/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.xml b/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.xml index 77f1f601555..f2d52f6847a 100644 --- a/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.xml +++ b/idea/idea-maven/testData/maven-inspections/dependencyWithNoExecution.xml @@ -18,6 +18,26 @@ kotlin-stdlib ${kotlin.version} + + org.jetbrains.kotlin + kotlin-stdlib-jre7 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jre8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jdk7 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jdk8 + ${kotlin.version} + org.jetbrains.kotlin kotlin-stdlib-js @@ -27,4 +47,8 @@ + + + +