From cc0a9070b9e9121922a2e29a142aa737b5f5d068 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 4 Oct 2017 13:42:12 +0300 Subject: [PATCH] Add kotlin.stdlib to module-info when configure Maven project (KT-19207) #KT-19207 In Progress --- .../jetbrains/kotlin/idea/maven/PomFile.kt | 16 ++- .../KotlinJavaMavenConfigurator.kt | 27 +++-- .../configuration/KotlinMavenConfigurator.kt | 16 ++- ...MavenConfigureProjectByChangingFileTest.kt | 21 +++- ...ureProjectByChangingFileTestGenerated.java | 6 + .../jvm/withJava9ModuleInfo/module-info.java | 3 + .../module-info_after.java | 4 + .../jvm/withJava9ModuleInfo/pom.xml | 41 +++++++ .../jvm/withJava9ModuleInfo/pom_after.xml | 84 ++++++++++++++ .../ConfigureKotlinInProjectUtils.kt | 13 ++- ...actConfigureProjectByChangingFileTest.java | 103 ++++++++++++++++++ 11 files changed, 311 insertions(+), 23 deletions(-) create mode 100644 idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/module-info.java create mode 100644 idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/module-info_after.java create mode 100644 idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/pom.xml create mode 100644 idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/pom_after.xml 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 69629b4c0f2..690253f77dc 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 @@ -16,6 +16,8 @@ package org.jetbrains.kotlin.idea.maven +import com.intellij.openapi.application.ApplicationManager +import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.module.Module import com.intellij.openapi.roots.ModuleRootManager import com.intellij.openapi.roots.SourceFolder @@ -33,6 +35,7 @@ import org.jetbrains.idea.maven.dom.MavenDomUtil import org.jetbrains.idea.maven.dom.model.* import org.jetbrains.idea.maven.model.MavenId import org.jetbrains.idea.maven.model.MavenPlugin +import org.jetbrains.idea.maven.project.MavenProject import org.jetbrains.idea.maven.project.MavenProjectsManager import org.jetbrains.idea.maven.utils.MavenArtifactScope import org.jetbrains.jps.model.java.JavaSourceRootType @@ -214,7 +217,16 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr fun addJavacExecutions(module: Module, kotlinPlugin: MavenDomPlugin) { val javacPlugin = ensurePluginAfter(addPlugin(MavenId("org.apache.maven.plugins", "maven-compiler-plugin", null)), kotlinPlugin) - val project = MavenProjectsManager.getInstance(module.project).findProject(module) ?: error("Can't find maven project for $module") + val project: MavenProject = + MavenProjectsManager.getInstance(module.project).findProject(module) ?: + run { + if (ApplicationManager.getApplication().isUnitTestMode) { + LOG.warn("WARNING: Bad project configuration in tests. Javac execution configuration was skipped.") + return + } + error("Can't find maven project for $module") + } + val plugin = project.findPlugin("org.apache.maven.plugins", "maven-compiler-plugin") if (isExecutionEnabled(plugin, "default-compile")) { @@ -501,6 +513,8 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr } companion object { + private val LOG = Logger.getInstance(PomFile::class.java) + fun forFileOrNull(xmlFile: XmlFile): PomFile? = MavenDomUtil.getMavenDomProjectModel(xmlFile.project, xmlFile.virtualFile)?.let { PomFile(xmlFile, it) } @Deprecated("We shouldn't use phase but additional compiler configuration in most cases") diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinJavaMavenConfigurator.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinJavaMavenConfigurator.kt index fb2bec7e091..2f015d8e4d3 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinJavaMavenConfigurator.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinJavaMavenConfigurator.kt @@ -18,7 +18,10 @@ package org.jetbrains.kotlin.idea.maven.configuration import com.intellij.openapi.module.Module import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.psi.PsiFile import org.jetbrains.idea.maven.dom.model.MavenDomPlugin +import org.jetbrains.kotlin.idea.configuration.NotificationMessageCollector +import org.jetbrains.kotlin.idea.configuration.addStdlibToJavaModuleInfo import org.jetbrains.kotlin.idea.configuration.hasKotlinJvmRuntimeInScope import org.jetbrains.kotlin.idea.maven.PomFile import org.jetbrains.kotlin.idea.versions.getDefaultJvmTarget @@ -28,17 +31,14 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform class KotlinJavaMavenConfigurator : KotlinMavenConfigurator(KotlinJavaMavenConfigurator.TEST_LIB_ID, false, KotlinJavaMavenConfigurator.NAME, KotlinJavaMavenConfigurator.PRESENTABLE_TEXT) { - override fun isKotlinModule(module: Module): Boolean { - return hasKotlinJvmRuntimeInScope(module) - } + override fun isKotlinModule(module: Module) = + hasKotlinJvmRuntimeInScope(module) - override fun isRelevantGoal(goalName: String): Boolean { - return goalName == PomFile.KotlinGoals.Compile - } + override fun isRelevantGoal(goalName: String) = + goalName == PomFile.KotlinGoals.Compile - override fun getStdlibArtifactId(module: Module, version: String): String { - return getStdlibArtifactId(ModuleRootManager.getInstance(module).sdk, version) - } + override fun getStdlibArtifactId(module: Module, version: String): String = + getStdlibArtifactId(ModuleRootManager.getInstance(module).sdk, version) override fun createExecutions(pomFile: PomFile, kotlinPlugin: MavenDomPlugin, module: Module) { createExecution(pomFile, kotlinPlugin, PomFile.DefaultPhases.Compile, PomFile.KotlinGoals.Compile, module, false) @@ -53,6 +53,15 @@ class KotlinJavaMavenConfigurator : KotlinMavenConfigurator(KotlinJavaMavenConfi } } + override fun configureModule(module: Module, file: PsiFile, version: String, collector: NotificationMessageCollector): Boolean { + if (!super.configureModule(module, file, version, collector)) { + return false + } + + addStdlibToJavaModuleInfo(module, collector) + return true + } + override val targetPlatform: TargetPlatform get() = JvmPlatform diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt index 5f18dc2f4b9..03171f1a75a 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/configuration/KotlinMavenConfigurator.kt @@ -118,7 +118,7 @@ abstract class KotlinMavenConfigurator for (module in excludeMavenChildrenModules(project, dialog.modulesToConfigure)) { val file = findModulePomFile(module) if (file != null && canConfigureFile(file)) { - changePomFile(module, file, dialog.kotlinVersion, collector) + configureModule(module, file, dialog.kotlinVersion, collector) OpenFileAction.openFile(file.virtualFile, project) } else { @@ -137,20 +137,23 @@ abstract class KotlinMavenConfigurator protected abstract fun createExecutions(pomFile: PomFile, kotlinPlugin: MavenDomPlugin, module: Module) protected abstract fun getStdlibArtifactId(module: Module, version: String): String - fun changePomFile( + open fun configureModule(module: Module, file: PsiFile, version: String, collector: NotificationMessageCollector): Boolean = + changePomFile(module, file, version, collector) + + private fun changePomFile( module: Module, file: PsiFile, version: String, - collector: NotificationMessageCollector) { - + collector: NotificationMessageCollector + ): Boolean { val virtualFile = file.virtualFile ?: error("Virtual file should exists for psi file " + file.name) val domModel = MavenDomUtil.getMavenDomProjectModel(module.project, virtualFile) if (domModel == null) { showErrorMessage(module.project, null) - return + return false } - val pom = PomFile.forFileOrNull(file as XmlFile) ?: return + val pom = PomFile.forFileOrNull(file as XmlFile) ?: return false pom.addProperty(KOTLIN_VERSION_PROPERTY, version) pom.addDependency(MavenId(GROUP_ID, getStdlibArtifactId(module, version), "\${$KOTLIN_VERSION_PROPERTY}"), MavenArtifactScope.COMPILE, null, false, null) @@ -176,6 +179,7 @@ abstract class KotlinMavenConfigurator CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(file) collector.addMessage(virtualFile.path + " was modified") + return true } protected open fun configurePlugin(pom: PomFile, plugin: MavenDomPlugin, module: Module, version: String) { diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/configuration/AbstractMavenConfigureProjectByChangingFileTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/configuration/AbstractMavenConfigureProjectByChangingFileTest.kt index 64f4ff67d9e..f32a0c2bf2b 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/configuration/AbstractMavenConfigureProjectByChangingFileTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/configuration/AbstractMavenConfigureProjectByChangingFileTest.kt @@ -18,10 +18,15 @@ package org.jetbrains.kotlin.idea.maven.configuration import com.intellij.openapi.command.WriteCommandAction import com.intellij.openapi.module.Module +import com.intellij.openapi.projectRoots.Sdk import com.intellij.psi.PsiFile import org.jetbrains.idea.maven.model.MavenConstants import org.jetbrains.kotlin.idea.configuration.AbstractConfigureProjectByChangingFileTest import org.jetbrains.kotlin.idea.configuration.NotificationMessageCollector +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.test.KotlinTestUtils +import org.jetbrains.kotlin.test.KotlinTestUtils.isAllFilesPresentTest +import java.io.File abstract class AbstractMavenConfigureProjectByChangingFileTest : AbstractConfigureProjectByChangingFileTest() { fun doTestWithMaven(path: String) { @@ -36,7 +41,21 @@ abstract class AbstractMavenConfigureProjectByChangingFileTest : AbstractConfigu override fun runConfigurator(module: Module, file: PsiFile, configurator: KotlinMavenConfigurator, version: String, collector: NotificationMessageCollector) { WriteCommandAction.runWriteCommandAction(module.project) { - configurator.changePomFile(module, file, version, collector) + configurator.configureModule(module, file, version, collector) } } + + override fun getProjectJDK(): Sdk { + if (!isAllFilesPresentTest(getTestName(false))) { + val root = KotlinTestUtils.getTestsRoot(this::class.java) + val dir = KotlinTestUtils.getTestDataFileName(this::class.java, name) + + val pomFile = File("$root/$dir", MavenConstants.POM_XML) + if (pomFile.readText().contains("9")) { + return PluginTestCaseBase.mockJdk9() + } + } + + return super.getProjectJDK() + } } diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/configuration/MavenConfigureProjectByChangingFileTestGenerated.java b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/configuration/MavenConfigureProjectByChangingFileTestGenerated.java index 587fe5e7766..ddefb0a0d0f 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/configuration/MavenConfigureProjectByChangingFileTestGenerated.java +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/configuration/MavenConfigureProjectByChangingFileTestGenerated.java @@ -79,6 +79,12 @@ public class MavenConfigureProjectByChangingFileTestGenerated extends AbstractMa String fileName = KotlinTestUtils.navigationMetadata("idea/idea-maven/testData/configurator/jvm/simpleProjectSnapshot/"); doTestWithMaven(fileName); } + + @TestMetadata("withJava9ModuleInfo") + public void testWithJava9ModuleInfo() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/"); + doTestWithMaven(fileName); + } } @TestMetadata("idea/idea-maven/testData/configurator/js") diff --git a/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/module-info.java b/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/module-info.java new file mode 100644 index 00000000000..696515864d9 --- /dev/null +++ b/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/module-info.java @@ -0,0 +1,3 @@ +module TestModule { + +} \ No newline at end of file diff --git a/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/module-info_after.java b/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/module-info_after.java new file mode 100644 index 00000000000..6484cb66f3d --- /dev/null +++ b/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/module-info_after.java @@ -0,0 +1,4 @@ +module TestModule { + requires kotlin.stdlib; + +} \ No newline at end of file diff --git a/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/pom.xml b/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/pom.xml new file mode 100644 index 00000000000..dfc9701b1a9 --- /dev/null +++ b/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/pom.xml @@ -0,0 +1,41 @@ + + + 4.0.0 + + maventest + maventest + 1.0-SNAPSHOT + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + 9 + 9 + + + + + + + \ No newline at end of file diff --git a/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/pom_after.xml b/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/pom_after.xml new file mode 100644 index 00000000000..bf437640c7f --- /dev/null +++ b/idea/idea-maven/testData/configurator/jvm/withJava9ModuleInfo/pom_after.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + maventest + maventest + 1.0-SNAPSHOT + + + $VERSION$ + + + + + org.jetbrains.kotlin + kotlin-stdlib-jre8 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-test + ${kotlin.version} + test + + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + + 1.8 + + + + org.apache.maven.plugins + maven-compiler-plugin + + + compile + compile + + compile + + + + testCompile + test-compile + + testCompile + + + + + 9 + 9 + + + + + + + \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt b/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt index 598e0af5921..f95b6587d76 100644 --- a/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/configuration/ConfigureKotlinInProjectUtils.kt @@ -284,17 +284,18 @@ private class LibraryKindSearchScope(val module: Module, } } -fun addStdlibToJavaModuleInfo(module: Module, collector: NotificationMessageCollector) { - if (module.sdk?.version?.isAtLeast(JavaSdkVersion.JDK_1_9) != true) return +fun addStdlibToJavaModuleInfo(module: Module, collector: NotificationMessageCollector): Boolean { + if (module.sdk?.version?.isAtLeast(JavaSdkVersion.JDK_1_9) != true) return false val project = module.project - val javaModule: PsiJavaModule = findFirstPsiJavaModule(module) ?: return + val javaModule: PsiJavaModule = findFirstPsiJavaModule(module) ?: return false val success = WriteCommandAction.runWriteCommandAction(project, Computable { KotlinAddRequiredModuleFix.addModuleRequirement(javaModule, KOTLIN_STDLIB_MODULE_NAME) }) - if (success) { - collector.addMessage("Added ${KOTLIN_STDLIB_MODULE_NAME} requirement to module-info in ${module.name}") - } + if (!success) return false + + collector.addMessage("Added $KOTLIN_STDLIB_MODULE_NAME requirement to module-info in ${module.name}") + return true } diff --git a/idea/tests/org/jetbrains/kotlin/idea/configuration/AbstractConfigureProjectByChangingFileTest.java b/idea/tests/org/jetbrains/kotlin/idea/configuration/AbstractConfigureProjectByChangingFileTest.java index d0fcd9d43d1..0a52ee8def2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/configuration/AbstractConfigureProjectByChangingFileTest.java +++ b/idea/tests/org/jetbrains/kotlin/idea/configuration/AbstractConfigureProjectByChangingFileTest.java @@ -18,18 +18,33 @@ package org.jetbrains.kotlin.idea.configuration; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.util.io.FileUtilRt; +import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiJavaModule; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testFramework.LightCodeInsightTestCase; +import com.intellij.testFramework.LightProjectDescriptor; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesUpdaterKt; import org.jetbrains.kotlin.test.InTextDirectivesUtils; import org.jetbrains.kotlin.test.KotlinTestUtils; import java.io.File; +import java.io.IOException; +import java.util.Objects; public abstract class AbstractConfigureProjectByChangingFileTest extends LightCodeInsightTestCase { private static final String DEFAULT_VERSION = "default_version"; + private PsiFile moduleInfoFile; + @Override protected void setUp() throws Exception { super.setUp(); @@ -39,12 +54,15 @@ public abstract class AbstractConfigureProjectByChangingFileTest