Reformat and cleanup idea-maven_main module

This commit is contained in:
Nikolay Krasko
2018-01-17 18:39:29 +03:00
parent 7f1cc81d39
commit 4a2440ea0f
23 changed files with 2059 additions and 1788 deletions
+1
View File
@@ -2,6 +2,7 @@
<dictionary name="Nikolay.Krasko"> <dictionary name="Nikolay.Krasko">
<words> <words>
<w>accessors</w> <w>accessors</w>
<w>coroutines</w>
<w>crossinline</w> <w>crossinline</w>
<w>fqname</w> <w>fqname</w>
<w>goto</w> <w>goto</w>
@@ -29,10 +29,36 @@ import java.net.HttpURLConnection
import java.net.URLEncoder import java.net.URLEncoder
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class KotlinMavenArchetypesProvider(val kotlinPluginVersion: String, val predefinedInternalMode: Boolean?) : MavenArchetypesProvider { class KotlinMavenArchetypesProvider(private val kotlinPluginVersion: String, private val predefinedInternalMode: Boolean?) :
MavenArchetypesProvider {
@Suppress("unused")
constructor() : this(KotlinPluginUtil.getPluginVersion(), null) constructor() : this(KotlinPluginUtil.getPluginVersion(), null)
val VERSIONS_LIST_URL = mavenSearchUrl("org.jetbrains.kotlin", packaging = "maven-archetype", rowsLimit = 1000) companion object {
private val VERSIONS_LIST_URL = mavenSearchUrl("org.jetbrains.kotlin", packaging = "maven-archetype", rowsLimit = 1000)
private fun mavenSearchUrl(
group: String,
artifactId: String? = null,
version: String? = null,
packaging: String? = null,
rowsLimit: Int = 20
): String {
val q = listOf(
"g" to group,
"a" to artifactId,
"v" to version,
"p" to packaging
)
.filter { it.second != null }.joinToString(separator = " AND ") { "${it.first}:\"${it.second}\"" }
return "http://search.maven.org/solrsearch/select?q=${q.encodeURL()}&core=gav&rows=$rowsLimit&wt=json"
}
private fun String.encodeURL() = URLEncoder.encode(this, "UTF-8")
}
private val versionPrefix by lazy { versionPrefix(kotlinPluginVersion) } private val versionPrefix by lazy { versionPrefix(kotlinPluginVersion) }
private val fallbackVersion = "1.0.3" private val fallbackVersion = "1.0.3"
private val internalMode: Boolean private val internalMode: Boolean
@@ -41,8 +67,7 @@ class KotlinMavenArchetypesProvider(val kotlinPluginVersion: String, val predefi
private val archetypesBlocking by lazy { private val archetypesBlocking by lazy {
try { try {
loadVersions().ifEmpty { fallbackArchetypes() } loadVersions().ifEmpty { fallbackArchetypes() }
} } catch (t: Throwable) {
catch (t: Throwable) {
fallbackArchetypes() fallbackArchetypes()
} }
} }
@@ -83,18 +108,6 @@ class KotlinMavenArchetypesProvider(val kotlinPluginVersion: String, val predefi
return versions.maxBy { MavenVersionComparable(it.version) } return versions.maxBy { MavenVersionComparable(it.version) }
} }
private fun mavenSearchUrl(group: String, artifactId: String? = null, version: String? = null, packaging: String? = null, rowsLimit: Int = 20): String {
val q = listOf(
"g" to group,
"a" to artifactId,
"v" to version,
"p" to packaging
)
.filter { it.second != null }.joinToString(separator = " AND ") { "${it.first}:\"${it.second}\"" }
return "http://search.maven.org/solrsearch/select?q=${q.encodeURL()}&core=gav&rows=$rowsLimit&wt=json"
}
private fun <R> connectAndApply(url: String, timeoutSeconds: Int = 15, block: (HttpURLConnection) -> R): R { private fun <R> connectAndApply(url: String, timeoutSeconds: Int = 15, block: (HttpURLConnection) -> R): R {
return HttpConfigurable.getInstance().openHttpConnection(url).use { urlConnection -> return HttpConfigurable.getInstance().openHttpConnection(url).use { urlConnection ->
val timeout = TimeUnit.SECONDS.toMillis(timeoutSeconds.toLong()).toInt() val timeout = TimeUnit.SECONDS.toMillis(timeoutSeconds.toLong()).toInt()
@@ -109,12 +122,9 @@ class KotlinMavenArchetypesProvider(val kotlinPluginVersion: String, val predefi
private fun <R> HttpURLConnection.use(block: (HttpURLConnection) -> R): R = private fun <R> HttpURLConnection.use(block: (HttpURLConnection) -> R): R =
try { try {
block(this) block(this)
} } finally {
finally {
disconnect() disconnect()
} }
private fun String.encodeURL() = URLEncoder.encode(this, "UTF-8")
private fun versionPrefix(version: String) = """^\d+\.\d+\.""".toRegex().find(version)?.value private fun versionPrefix(version: String) = """^\d+\.\d+\.""".toRegex().find(version)?.value
} }
@@ -62,30 +62,42 @@ interface MavenProjectImportHandler {
class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ARTIFACT_ID) { class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ARTIFACT_ID) {
companion object { companion object {
val KOTLIN_PLUGIN_GROUP_ID = "org.jetbrains.kotlin" const val KOTLIN_PLUGIN_GROUP_ID = "org.jetbrains.kotlin"
val KOTLIN_PLUGIN_ARTIFACT_ID = "kotlin-maven-plugin" const val KOTLIN_PLUGIN_ARTIFACT_ID = "kotlin-maven-plugin"
val KOTLIN_PLUGIN_SOURCE_DIRS_CONFIG = "sourceDirs" const val KOTLIN_PLUGIN_SOURCE_DIRS_CONFIG = "sourceDirs"
} }
override fun preProcess(module: Module, mavenProject: MavenProject, changes: MavenProjectChanges, modifiableModelsProvider: IdeModifiableModelsProvider) { override fun preProcess(
module: Module,
mavenProject: MavenProject,
changes: MavenProjectChanges,
modifiableModelsProvider: IdeModifiableModelsProvider
) {
} }
override fun process(modifiableModelsProvider: IdeModifiableModelsProvider, override fun process(
modifiableModelsProvider: IdeModifiableModelsProvider,
module: Module, module: Module,
rootModel: MavenRootModelAdapter, rootModel: MavenRootModelAdapter,
mavenModel: MavenProjectsTree, mavenModel: MavenProjectsTree,
mavenProject: MavenProject, mavenProject: MavenProject,
changes: MavenProjectChanges, changes: MavenProjectChanges,
mavenProjectToModuleName: MutableMap<MavenProject, String>, mavenProjectToModuleName: MutableMap<MavenProject, String>,
postTasks: MutableList<MavenProjectsProcessorTask>) { postTasks: MutableList<MavenProjectsProcessorTask>
) {
if (changes.plugins) { if (changes.plugins) {
contributeSourceDirectories(mavenProject, module, rootModel) contributeSourceDirectories(mavenProject, module, rootModel)
} }
} }
override fun postProcess(module: Module, mavenProject: MavenProject, changes: MavenProjectChanges, modifiableModelsProvider: IdeModifiableModelsProvider) { override fun postProcess(
module: Module,
mavenProject: MavenProject,
changes: MavenProjectChanges,
modifiableModelsProvider: IdeModifiableModelsProvider
) {
super.postProcess(module, mavenProject, changes, modifiableModelsProvider) super.postProcess(module, mavenProject, changes, modifiableModelsProvider)
if (changes.dependencies) { if (changes.dependencies) {
@@ -108,7 +120,8 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
private fun scheduleDownloadStdlibSources(mavenProject: MavenProject, module: Module) { private fun scheduleDownloadStdlibSources(mavenProject: MavenProject, module: Module) {
// TODO: here we have to process all kotlin libraries but for now we only handle standard libraries // TODO: here we have to process all kotlin libraries but for now we only handle standard libraries
val artifacts = mavenProject.dependencyArtifactIndex.data[KOTLIN_PLUGIN_GROUP_ID]?.values?.flatMap { it.filter { it.isResolved } } ?: emptyList() val artifacts = mavenProject.dependencyArtifactIndex.data[KOTLIN_PLUGIN_GROUP_ID]?.values?.flatMap { it.filter { it.isResolved } }
?: emptyList()
val librariesWithNoSources = ArrayList<Library>() val librariesWithNoSources = ArrayList<Library>()
OrderEnumerator.orderEntries(module).forEachLibrary { library -> OrderEnumerator.orderEntries(module).forEachLibrary { library ->
@@ -121,21 +134,26 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
val toBeDownloaded = artifacts.filter { it.libraryName in libraryNames } val toBeDownloaded = artifacts.filter { it.libraryName in libraryNames }
if (toBeDownloaded.isNotEmpty()) { if (toBeDownloaded.isNotEmpty()) {
MavenProjectsManager.getInstance(module.project).scheduleArtifactsDownloading(listOf(mavenProject), toBeDownloaded, true, false, AsyncResult()) MavenProjectsManager.getInstance(module.project)
.scheduleArtifactsDownloading(listOf(mavenProject), toBeDownloaded, true, false, AsyncResult())
} }
} }
private fun getCompilerArgumentsByConfigurationElement(mavenProject: MavenProject, private fun getCompilerArgumentsByConfigurationElement(
mavenProject: MavenProject,
configuration: Element?, configuration: Element?,
platform: TargetPlatformKind<*>): List<String> { platform: TargetPlatformKind<*>
): List<String> {
val arguments = when (platform) { val arguments = when (platform) {
is TargetPlatformKind.Jvm -> K2JVMCompilerArguments() is TargetPlatformKind.Jvm -> K2JVMCompilerArguments()
is TargetPlatformKind.JavaScript -> K2JSCompilerArguments() TargetPlatformKind.JavaScript -> K2JSCompilerArguments()
is TargetPlatformKind.Common -> K2MetadataCompilerArguments() TargetPlatformKind.Common -> K2MetadataCompilerArguments()
} }
arguments.apiVersion = configuration?.getChild("apiVersion")?.text ?: mavenProject.properties["kotlin.compiler.apiVersion"]?.toString() arguments.apiVersion = configuration?.getChild("apiVersion")?.text ?:
arguments.languageVersion = configuration?.getChild("languageVersion")?.text ?: mavenProject.properties["kotlin.compiler.languageVersion"]?.toString() mavenProject.properties["kotlin.compiler.apiVersion"]?.toString()
arguments.languageVersion = configuration?.getChild("languageVersion")?.text ?:
mavenProject.properties["kotlin.compiler.languageVersion"]?.toString()
arguments.multiPlatform = configuration?.getChild("multiPlatform")?.text?.trim()?.toBoolean() ?: false arguments.multiPlatform = configuration?.getChild("multiPlatform")?.text?.trim()?.toBoolean() ?: false
arguments.suppressWarnings = configuration?.getChild("nowarn")?.text?.trim()?.toBoolean() ?: false arguments.suppressWarnings = configuration?.getChild("nowarn")?.text?.trim()?.toBoolean() ?: false
@@ -147,7 +165,8 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
is K2JVMCompilerArguments -> { is K2JVMCompilerArguments -> {
arguments.classpath = configuration?.getChild("classpath")?.text arguments.classpath = configuration?.getChild("classpath")?.text
arguments.jdkHome = configuration?.getChild("jdkHome")?.text arguments.jdkHome = configuration?.getChild("jdkHome")?.text
arguments.jvmTarget = configuration?.getChild("jvmTarget")?.text ?: mavenProject.properties["kotlin.compiler.jvmTarget"]?.toString() arguments.jvmTarget = configuration?.getChild("jvmTarget")?.text ?:
mavenProject.properties["kotlin.compiler.jvmTarget"]?.toString()
} }
is K2JSCompilerArguments -> { is K2JSCompilerArguments -> {
arguments.sourceMap = configuration?.getChild("sourceMap")?.text?.trim()?.toBoolean() ?: false arguments.sourceMap = configuration?.getChild("sourceMap")?.text?.trim()?.toBoolean() ?: false
@@ -181,11 +200,13 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
return ArgumentUtils.convertArgumentsToStringList(arguments) return ArgumentUtils.convertArgumentsToStringList(arguments)
} }
private val compilationGoals = listOf(PomFile.KotlinGoals.Compile, private val compilationGoals = listOf(
PomFile.KotlinGoals.Compile,
PomFile.KotlinGoals.TestCompile, PomFile.KotlinGoals.TestCompile,
PomFile.KotlinGoals.Js, PomFile.KotlinGoals.Js,
PomFile.KotlinGoals.TestJs, PomFile.KotlinGoals.TestJs,
PomFile.KotlinGoals.MetaData) PomFile.KotlinGoals.MetaData
)
private fun configureFacet(mavenProject: MavenProject, modifiableModelsProvider: IdeModifiableModelsProvider, module: Module) { private fun configureFacet(mavenProject: MavenProject, modifiableModelsProvider: IdeModifiableModelsProvider, module: Module) {
val mavenPlugin = mavenProject.findPlugin(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID) ?: return val mavenPlugin = mavenProject.findPlugin(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID) ?: return
@@ -197,8 +218,8 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
val configuredPlatform = kotlinFacet.configuration.settings.targetPlatformKind!! val configuredPlatform = kotlinFacet.configuration.settings.targetPlatformKind!!
val configuration = mavenPlugin.configurationElement val configuration = mavenPlugin.configurationElement
val sharedArguments = getCompilerArgumentsByConfigurationElement(mavenProject, configuration, configuredPlatform) val sharedArguments = getCompilerArgumentsByConfigurationElement(mavenProject, configuration, configuredPlatform)
val executionArguments = mavenPlugin.executions?.filter { it.goals.any { it in compilationGoals } } val executionArguments = mavenPlugin.executions
?.firstOrNull() ?.firstOrNull { it.goals.any { it in compilationGoals } }
?.configurationElement?.let { getCompilerArgumentsByConfigurationElement(mavenProject, it, configuredPlatform) } ?.configurationElement?.let { getCompilerArgumentsByConfigurationElement(mavenProject, it, configuredPlatform) }
parseCompilerArgumentsToFacet(sharedArguments, emptyList(), kotlinFacet, modifiableModelsProvider) parseCompilerArgumentsToFacet(sharedArguments, emptyList(), kotlinFacet, modifiableModelsProvider)
if (executionArguments != null) { if (executionArguments != null) {
@@ -209,11 +230,12 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
kotlinFacet.noVersionAutoAdvance() kotlinFacet.noVersionAutoAdvance()
} }
private fun detectPlatform(mavenProject: MavenProject) = detectPlatformByExecutions(mavenProject) ?: private fun detectPlatform(mavenProject: MavenProject) =
detectPlatformByLibraries(mavenProject) detectPlatformByExecutions(mavenProject) ?: detectPlatformByLibraries(mavenProject)
private fun detectPlatformByExecutions(mavenProject: MavenProject): TargetPlatformKind<*>? { private fun detectPlatformByExecutions(mavenProject: MavenProject): TargetPlatformKind<*>? {
return mavenProject.findPlugin(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ARTIFACT_ID)?.executions?.flatMap { it.goals }?.mapNotNull { goal -> return mavenProject.findPlugin(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_ARTIFACT_ID)?.executions?.flatMap { it.goals }
?.mapNotNull { goal ->
when (goal) { when (goal) {
PomFile.KotlinGoals.Compile, PomFile.KotlinGoals.TestCompile -> TargetPlatformKind.Jvm[JvmTarget.JVM_1_6] PomFile.KotlinGoals.Compile, PomFile.KotlinGoals.TestCompile -> TargetPlatformKind.Jvm[JvmTarget.JVM_1_6]
PomFile.KotlinGoals.Js, PomFile.KotlinGoals.TestJs -> TargetPlatformKind.JavaScript PomFile.KotlinGoals.Js, PomFile.KotlinGoals.TestJs -> TargetPlatformKind.JavaScript
@@ -272,7 +294,9 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
private fun collectSourceDirectories(mavenProject: MavenProject): List<Pair<SourceType, String>> = private fun collectSourceDirectories(mavenProject: MavenProject): List<Pair<SourceType, String>> =
mavenProject.plugins.filter { it.isKotlinPlugin() }.flatMap { plugin -> mavenProject.plugins.filter { it.isKotlinPlugin() }.flatMap { plugin ->
plugin.configurationElement.sourceDirectories().map { SourceType.PROD to it } + plugin.configurationElement.sourceDirectories().map { SourceType.PROD to it } +
plugin.executions.flatMap { execution -> execution.configurationElement.sourceDirectories().map { execution.sourceType() to it } } plugin.executions.flatMap { execution ->
execution.configurationElement.sourceDirectories().map { execution.sourceType() to it }
}
}.distinct() }.distinct()
private fun setImplementedModuleName(kotlinFacet: KotlinFacet, mavenProject: MavenProject, module: Module) { private fun setImplementedModuleName(kotlinFacet: KotlinFacet, mavenProject: MavenProject, module: Module) {
@@ -288,8 +312,13 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
} }
} }
private fun MavenPlugin.isKotlinPlugin() = groupId == KotlinMavenImporter.KOTLIN_PLUGIN_GROUP_ID && artifactId == KotlinMavenImporter.KOTLIN_PLUGIN_ARTIFACT_ID private fun MavenPlugin.isKotlinPlugin() =
private fun Element?.sourceDirectories(): List<String> = this?.getChildren(KotlinMavenImporter.KOTLIN_PLUGIN_SOURCE_DIRS_CONFIG)?.flatMap { it.children ?: emptyList() }?.map { it.textTrim } ?: emptyList() groupId == KotlinMavenImporter.KOTLIN_PLUGIN_GROUP_ID && artifactId == KotlinMavenImporter.KOTLIN_PLUGIN_ARTIFACT_ID
private fun Element?.sourceDirectories(): List<String> =
this?.getChildren(KotlinMavenImporter.KOTLIN_PLUGIN_SOURCE_DIRS_CONFIG)?.flatMap { it.children ?: emptyList() }?.map { it.textTrim }
?: emptyList()
private fun MavenPlugin.Execution.sourceType() = private fun MavenPlugin.Execution.sourceType() =
goals.map { if (isTestGoalName(it)) SourceType.TEST else SourceType.PROD } goals.map { if (isTestGoalName(it)) SourceType.TEST else SourceType.PROD }
.distinct() .distinct()
@@ -301,14 +330,14 @@ private enum class SourceType {
PROD, TEST PROD, TEST
} }
@State(name = "AutoImportedSourceRoots", @State(
storages = arrayOf( name = "AutoImportedSourceRoots",
Storage(id = "other", file = StoragePathMacros.MODULE_FILE) storages = [(Storage(id = "other", file = StoragePathMacros.MODULE_FILE))]
)) )
class KotlinImporterComponent : PersistentStateComponent<KotlinImporterComponent.State> { class KotlinImporterComponent : PersistentStateComponent<KotlinImporterComponent.State> {
class State(var directories: List<String> = ArrayList()) class State(var directories: List<String> = ArrayList())
val addedSources = Collections.synchronizedSet(HashSet<String>()) val addedSources: MutableSet<String> = Collections.synchronizedSet(HashSet<String>())
override fun loadState(state: State?) { override fun loadState(state: State?) {
addedSources.clear() addedSources.clear()
@@ -47,8 +47,12 @@ import java.util.*
fun kotlinPluginId(version: String?) = MavenId(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID, version) fun kotlinPluginId(version: String?) = MavenId(KotlinMavenConfigurator.GROUP_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID, version)
class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomProjectModel) { class PomFile private constructor(private val xmlFile: XmlFile, val domModel: MavenDomProjectModel) {
constructor(xmlFile: XmlFile) : this(xmlFile, MavenDomUtil.getMavenDomProjectModel(xmlFile.project, xmlFile.virtualFile) ?: throw IllegalStateException("No DOM model found for pom ${xmlFile.name}")) constructor(xmlFile: XmlFile) : this(
xmlFile,
MavenDomUtil.getMavenDomProjectModel(xmlFile.project, xmlFile.virtualFile)
?: throw IllegalStateException("No DOM model found for pom ${xmlFile.name}")
)
private val nodesByName = HashMap<String, XmlTag>() private val nodesByName = HashMap<String, XmlTag>()
private val projectElement: XmlTag private val projectElement: XmlTag
@@ -62,12 +66,10 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
if (element is XmlTag && element.localName in recommendedElementsOrder && element.parent === projectElement) { if (element is XmlTag && element.localName in recommendedElementsOrder && element.parent === projectElement) {
nodesByName[element.localName] = element nodesByName[element.localName] = element
} } else if (element is XmlTag && element.localName == "project") {
else if (element is XmlTag && element.localName == "project") {
projectElement = element projectElement = element
element.acceptChildren(this) element.acceptChildren(this)
} } else {
else {
element.acceptChildren(this) element.acceptChildren(this)
} }
} }
@@ -86,13 +88,11 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
val textNode = tag.children.filterIsInstance<XmlText>().firstOrNull() val textNode = tag.children.filterIsInstance<XmlText>().firstOrNull()
if (textNode != null) { if (textNode != null) {
textNode.value = value textNode.value = value
} } else {
else {
tag.replace(projectElement.createChildTag(name, value)) tag.replace(projectElement.createChildTag(name, value))
} }
} }
} } else {
else {
properties.add(projectElement.createChildTag(name, value)) properties.add(projectElement.createChildTag(name, value))
} }
} }
@@ -102,7 +102,13 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
return propertiesNode.findFirstSubTag(name) return propertiesNode.findFirstSubTag(name)
} }
fun addDependency(artifact: MavenId, scope: MavenArtifactScope? = null, classifier: String? = null, optional: Boolean = false, systemPath: String? = null): MavenDomDependency { fun addDependency(
artifact: MavenId,
scope: MavenArtifactScope? = null,
classifier: String? = null,
optional: Boolean = false,
systemPath: String? = null
): MavenDomDependency {
require(systemPath == null || scope == MavenArtifactScope.SYSTEM) { "systemPath is only applicable for system scope dependency" } require(systemPath == null || scope == MavenArtifactScope.SYSTEM) { "systemPath is only applicable for system scope dependency" }
require(artifact.groupId != null) { "groupId shouldn't be null" } require(artifact.groupId != null) { "groupId shouldn't be null" }
require(artifact.artifactId != null) { "artifactId shouldn't be null" } require(artifact.artifactId != null) { "artifactId shouldn't be null" }
@@ -163,7 +169,7 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
return true return true
} }
fun ensurePluginAfter(plugin: MavenDomPlugin, referencePlugin: MavenDomPlugin): MavenDomPlugin { private fun ensurePluginAfter(plugin: MavenDomPlugin, referencePlugin: MavenDomPlugin): MavenDomPlugin {
if (!isPluginAfter(plugin, referencePlugin)) { if (!isPluginAfter(plugin, referencePlugin)) {
// rearrange // rearrange
val referenceElement = referencePlugin.xmlElement!! val referenceElement = referencePlugin.xmlElement!!
@@ -180,8 +186,9 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
fun findKotlinExecutions(vararg goals: String) = findKotlinExecutions().filter { it.goals.goals.any { it.rawText in goals } } fun findKotlinExecutions(vararg goals: String) = findKotlinExecutions().filter { it.goals.goals.any { it.rawText in goals } }
fun findKotlinExecutions() = findKotlinPlugins().flatMap { it.executions.executions } fun findKotlinExecutions() = findKotlinPlugins().flatMap { it.executions.executions }
fun findExecutions(plugin: MavenDomPlugin) = plugin.executions.executions private fun findExecutions(plugin: MavenDomPlugin) = plugin.executions.executions
fun findExecutions(plugin: MavenDomPlugin, vararg goals: String) = findExecutions(plugin).filter { it.goals.goals.any { it.rawText in goals } } fun findExecutions(plugin: MavenDomPlugin, vararg goals: String) =
findExecutions(plugin).filter { it.goals.goals.any { it.rawText in goals } }
fun addExecution(plugin: MavenDomPlugin, executionId: String, phase: String, goals: List<String>): MavenDomPluginExecution { fun addExecution(plugin: MavenDomPlugin, executionId: String, phase: String, goals: List<String>): MavenDomPluginExecution {
require(executionId.isNotEmpty()) { "executionId shouldn't be empty" } require(executionId.isNotEmpty()) { "executionId shouldn't be empty" }
@@ -200,7 +207,14 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
return execution return execution
} }
fun addKotlinExecution(module: Module, plugin: MavenDomPlugin, executionId: String, phase: String, isTest: Boolean, goals: List<String>) { fun addKotlinExecution(
module: Module,
plugin: MavenDomPlugin,
executionId: String,
phase: String,
isTest: Boolean,
goals: List<String>
) {
val execution = addExecution(plugin, executionId, phase, goals) val execution = addExecution(plugin, executionId, phase, goals)
val sourceDirs = ModuleRootManager.getInstance(module) val sourceDirs = ModuleRootManager.getInstance(module)
@@ -212,14 +226,14 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
executionSourceDirs(execution, sourceDirs) executionSourceDirs(execution, sourceDirs)
} }
fun isPluginExecutionMissing(plugin: MavenPlugin?, excludedExecutionId: String, goal: String) = plugin == null || plugin.executions.none { it.executionId != excludedExecutionId && goal in it.goals } fun isPluginExecutionMissing(plugin: MavenPlugin?, excludedExecutionId: String, goal: String) =
plugin == null || plugin.executions.none { it.executionId != excludedExecutionId && goal in it.goals }
fun addJavacExecutions(module: Module, kotlinPlugin: MavenDomPlugin) { fun addJavacExecutions(module: Module, kotlinPlugin: MavenDomPlugin) {
val javacPlugin = ensurePluginAfter(addPlugin(MavenId("org.apache.maven.plugins", "maven-compiler-plugin", null)), kotlinPlugin) val javacPlugin = ensurePluginAfter(addPlugin(MavenId("org.apache.maven.plugins", "maven-compiler-plugin", null)), kotlinPlugin)
val project: MavenProject = val project: MavenProject =
MavenProjectsManager.getInstance(module.project).findProject(module) ?: MavenProjectsManager.getInstance(module.project).findProject(module) ?: run {
run {
if (ApplicationManager.getApplication().isUnitTestMode) { if (ApplicationManager.getApplication().isUnitTestMode) {
LOG.warn("WARNING: Bad project configuration in tests. Javac execution configuration was skipped.") LOG.warn("WARNING: Bad project configuration in tests. Javac execution configuration was skipped.")
return return
@@ -261,7 +275,8 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
// TODO: getPhase has been added as per https://youtrack.jetbrains.com/issue/IDEA-153582 and available only in latest IDEAs // TODO: getPhase has been added as per https://youtrack.jetbrains.com/issue/IDEA-153582 and available only in latest IDEAs
return plugin.executions.filter { it.executionId == executionId }.all { execution -> return plugin.executions.filter { it.executionId == executionId }.all { execution ->
execution::class.java.methods.filter { it.name == "getPhase" && it.parameterTypes.isEmpty() }.all { it.invoke(execution) == DefaultPhases.None } execution::class.java.methods.filter { it.name == "getPhase" && it.parameterTypes.isEmpty() }
.all { it.invoke(execution) == DefaultPhases.None }
} }
} }
@@ -272,20 +287,17 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
val defaultDir = if (isTest) "test" else "main" val defaultDir = if (isTest) "test" else "main"
val singleDirectoryElement = if (isTest) { val singleDirectoryElement = if (isTest) {
domModel.build.testSourceDirectory domModel.build.testSourceDirectory
} } else {
else {
domModel.build.sourceDirectory domModel.build.sourceDirectory
} }
if (sourceDirs.isEmpty() || sourceDirs.singleOrNull() == "src/$defaultDir/java") { if (sourceDirs.isEmpty() || sourceDirs.singleOrNull() == "src/$defaultDir/java") {
execution.configuration.xmlTag?.findSubTags("sourceDirs")?.forEach { it.deleteCascade() } execution.configuration.xmlTag?.findSubTags("sourceDirs")?.forEach { it.deleteCascade() }
singleDirectoryElement.undefine() singleDirectoryElement.undefine()
} } else if (sourceDirs.size == 1 && !forceSingleSource) {
else if (sourceDirs.size == 1 && !forceSingleSource) {
singleDirectoryElement.stringValue = sourceDirs.single() singleDirectoryElement.stringValue = sourceDirs.single()
execution.configuration.xmlTag?.findSubTags("sourceDirs")?.forEach { it.deleteCascade() } execution.configuration.xmlTag?.findSubTags("sourceDirs")?.forEach { it.deleteCascade() }
} } else {
else {
val sourceDirsTag = executionConfiguration(execution, "sourceDirs") val sourceDirsTag = executionConfiguration(execution, "sourceDirs")
val newSourceDirsTag = execution.configuration.createChildTag("sourceDirs") val newSourceDirsTag = execution.configuration.createChildTag("sourceDirs")
for (dir in sourceDirs) { for (dir in sourceDirs) {
@@ -303,7 +315,7 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
?: emptyList() ?: emptyList()
} }
fun executionConfiguration(execution: MavenDomPluginExecution, name: String): XmlTag { private fun executionConfiguration(execution: MavenDomPluginExecution, name: String): XmlTag {
val configurationTag = execution.configuration.ensureTagExists()!! val configurationTag = execution.configuration.ensureTagExists()!!
val existingTag = configurationTag.findSubTags(name).firstOrNull() val existingTag = configurationTag.findSubTags(name).firstOrNull()
@@ -320,39 +332,70 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
val existingTag = configurationTag.findFirstSubTag(optionName) val existingTag = configurationTag.findFirstSubTag(optionName)
if (existingTag != null) { if (existingTag != null) {
existingTag.value.text = optionValue existingTag.value.text = optionValue
} } else {
else {
configurationTag.add(configurationTag.createChildTag(optionName, optionValue)) configurationTag.add(configurationTag.createChildTag(optionName, optionValue))
} }
return configurationTag return configurationTag
} }
fun addPluginRepository(id: String, name: String, url: String, snapshots: Boolean = false, releases: Boolean = true): MavenDomRepository { private fun addPluginRepository(
id: String,
name: String,
url: String,
snapshots: Boolean = false,
releases: Boolean = true
): MavenDomRepository {
ensurePluginRepositories() ensurePluginRepositories()
return addRepository(id, name, url, snapshots, releases, { domModel.pluginRepositories.pluginRepositories }, { domModel.pluginRepositories.addPluginRepository() }) return addRepository(
id,
name,
url,
snapshots,
releases,
{ domModel.pluginRepositories.pluginRepositories },
{ domModel.pluginRepositories.addPluginRepository() })
} }
fun addPluginRepository(description: RepositoryDescription) { fun addPluginRepository(description: RepositoryDescription) {
addPluginRepository(description.id, description.name, description.url, description.isSnapshot, true) addPluginRepository(description.id, description.name, description.url, description.isSnapshot, true)
} }
fun addLibraryRepository(id: String, name: String, url: String, snapshots: Boolean = false, releases: Boolean = true): MavenDomRepository { private fun addLibraryRepository(
id: String,
name: String,
url: String,
snapshots: Boolean = false,
releases: Boolean = true
): MavenDomRepository {
ensureRepositories() ensureRepositories()
return addRepository(id, name, url, snapshots, releases, { domModel.repositories.repositories }, { domModel.repositories.addRepository() }) return addRepository(
id,
name,
url,
snapshots,
releases,
{ domModel.repositories.repositories },
{ domModel.repositories.addRepository() })
} }
fun addLibraryRepository(description: RepositoryDescription) { fun addLibraryRepository(description: RepositoryDescription) {
addLibraryRepository(description.id, description.name, description.url, description.isSnapshot, true) addLibraryRepository(description.id, description.name, description.url, description.isSnapshot, true)
} }
private fun addRepository(id: String, name: String, url: String, snapshots: Boolean, releases: Boolean, existing: () -> List<MavenDomRepository>, create: () -> MavenDomRepository): MavenDomRepository { private fun addRepository(
id: String,
name: String,
url: String,
snapshots: Boolean,
releases: Boolean,
existing: () -> List<MavenDomRepository>,
create: () -> MavenDomRepository
): MavenDomRepository {
val repository = val repository =
existing().firstOrNull { it.id.stringValue == id } ?: existing().firstOrNull { it.id.stringValue == id } ?: existing().firstOrNull { it.url.stringValue == url } ?: create()
existing().firstOrNull { it.url.stringValue == url } ?:
create()
if (repository.id.isEmpty()) { if (repository.id.isEmpty()) {
repository.id.stringValue = id repository.id.stringValue = id
@@ -371,19 +414,14 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
return repository return repository
} }
fun hasPlugin(artifact: MavenId) = domModel.build.plugins.plugins.any { it.matches(artifact) }
fun hasDependency(artifact: MavenId, scope: MavenArtifactScope? = null) =
domModel.dependencies.dependencies.any { it.matches(artifact, scope) }
fun findDependencies(artifact: MavenId, scope: MavenArtifactScope? = null) = fun findDependencies(artifact: MavenId, scope: MavenArtifactScope? = null) =
domModel.dependencies.dependencies.filter { it.matches(artifact, scope) } domModel.dependencies.dependencies.filter { it.matches(artifact, scope) }
fun ensureBuild(): XmlTag = ensureElement(projectElement, "build") private fun ensureBuild(): XmlTag = ensureElement(projectElement, "build")
fun ensureDependencies(): XmlTag = ensureElement(projectElement, "dependencies") private fun ensureDependencies(): XmlTag = ensureElement(projectElement, "dependencies")
fun ensurePluginRepositories(): XmlTag = ensureElement(projectElement, "pluginRepositories") private fun ensurePluginRepositories(): XmlTag = ensureElement(projectElement, "pluginRepositories")
fun ensureRepositories(): XmlTag = ensureElement(projectElement, "repositories") private fun ensureRepositories(): XmlTag = ensureElement(projectElement, "repositories")
private fun MavenDomPlugin.isKotlinMavenPlugin() = groupId.stringValue == KotlinMavenConfigurator.GROUP_ID private fun MavenDomPlugin.isKotlinMavenPlugin() = groupId.stringValue == KotlinMavenConfigurator.GROUP_ID
&& artifactId.stringValue == KotlinMavenConfigurator.MAVEN_PLUGIN_ID && artifactId.stringValue == KotlinMavenConfigurator.MAVEN_PLUGIN_ID
@@ -400,13 +438,13 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
private fun MavenId.withoutJDKSpecificSuffix() = MavenId( private fun MavenId.withoutJDKSpecificSuffix() = MavenId(
groupId, groupId,
artifactId?.substringBeforeLast("-jre")?.substringBeforeLast("-jdk"), artifactId?.substringBeforeLast("-jre")?.substringBeforeLast("-jdk"),
null) null
)
private fun MavenDomElement.createChildTag(name: String, value: String? = null) = xmlTag.createChildTag(name, value) private fun MavenDomElement.createChildTag(name: String, value: String? = null) = xmlTag.createChildTag(name, value)
private fun XmlTag.createChildTag(name: String, value: String? = null) = createChildTag(name, namespace, value, false)!! private fun XmlTag.createChildTag(name: String, value: String? = null) = createChildTag(name, namespace, value, false)!!
tailrec private tailrec fun XmlTag.deleteCascade() {
private fun XmlTag.deleteCascade() {
val oldParent = this.parentTag val oldParent = this.parentTag
delete() delete()
@@ -451,12 +489,12 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
private fun insertEmptyLines(node: XmlTag) { private fun insertEmptyLines(node: XmlTag) {
node.prevSibling?.let { before -> node.prevSibling?.let { before ->
if (!(before.hasEmptyLine() || before.lastChild?.hasEmptyLine() ?: false)) { if (!(before.hasEmptyLine() || before.lastChild?.hasEmptyLine() == true)) {
node.parent.addBefore(createEmptyLine(), node) node.parent.addBefore(createEmptyLine(), node)
} }
} }
node.nextSibling?.let { after -> node.nextSibling?.let { after ->
if (!(after.hasEmptyLine() || after.firstChild?.hasEmptyLine() ?: false)) { if (!(after.hasEmptyLine() || after.firstChild?.hasEmptyLine() == true)) {
node.parent.addAfter(createEmptyLine(), node) node.parent.addAfter(createEmptyLine(), node)
} }
} }
@@ -481,45 +519,47 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
@Suppress("Unused") @Suppress("Unused")
object DefaultPhases { object DefaultPhases {
val None = "none" const val None = "none"
val Validate = "validate" const val Validate = "validate"
val Initialize = "initialize" const val Initialize = "initialize"
val GenerateSources = "generate-sources" const val GenerateSources = "generate-sources"
val ProcessSources = "process-sources" const val ProcessSources = "process-sources"
val GenerateResources = "generate-resources" const val GenerateResources = "generate-resources"
val ProcessResources = "process-resources" const val ProcessResources = "process-resources"
val Compile = "compile" const val Compile = "compile"
val ProcessClasses = "process-classes" const val ProcessClasses = "process-classes"
val GenerateTestSources = "generate-test-sources" const val GenerateTestSources = "generate-test-sources"
val ProcessTestSources = "process-test-sources" const val ProcessTestSources = "process-test-sources"
val GenerateTestResources = "generate-test-resources" const val GenerateTestResources = "generate-test-resources"
val ProcessTestResources = "process-test-resources" const val ProcessTestResources = "process-test-resources"
val TestCompile = "test-compile" const val TestCompile = "test-compile"
val ProcessTestClasses = "process-test-classes" const val ProcessTestClasses = "process-test-classes"
val Test = "test" const val Test = "test"
val PreparePackage = "prepare-package" const val PreparePackage = "prepare-package"
val Package = "package" const val Package = "package"
val PreIntegrationTest = "pre-integration-test" const val PreIntegrationTest = "pre-integration-test"
val IntegrationTest = "integration-test" const val IntegrationTest = "integration-test"
val PostIntegrationTest = "post-integration-test" const val PostIntegrationTest = "post-integration-test"
val Verify = "verify" const val Verify = "verify"
val Install = "install" const val Install = "install"
val Deploy = "deploy" const val Deploy = "deploy"
} }
object KotlinGoals { object KotlinGoals {
val Compile = "compile" const val Compile = "compile"
val TestCompile = "test-compile" const val TestCompile = "test-compile"
val Js = "js" const val Js = "js"
val TestJs = "test-js" const val TestJs = "test-js"
val MetaData = "metadata" const val MetaData = "metadata"
} }
companion object { companion object {
private val LOG = Logger.getInstance(PomFile::class.java) private val LOG = Logger.getInstance(PomFile::class.java)
fun forFileOrNull(xmlFile: XmlFile): PomFile? = MavenDomUtil.getMavenDomProjectModel(xmlFile.project, xmlFile.virtualFile)?.let { PomFile(xmlFile, it) } fun forFileOrNull(xmlFile: XmlFile): PomFile? =
MavenDomUtil.getMavenDomProjectModel(xmlFile.project, xmlFile.virtualFile)?.let { PomFile(xmlFile, it) }
@Suppress("DeprecatedCallableAddReplaceWith")
@Deprecated("We shouldn't use phase but additional compiler configuration in most cases") @Deprecated("We shouldn't use phase but additional compiler configuration in most cases")
fun getPhase(hasJavaFiles: Boolean, isTest: Boolean) = when { fun getPhase(hasJavaFiles: Boolean, isTest: Boolean) = when {
hasJavaFiles -> when { hasJavaFiles -> when {
@@ -586,9 +626,13 @@ class PomFile private constructor(val xmlFile: XmlFile, val domModel: MavenDomPr
} }
fun PomFile.changeLanguageVersion(languageVersion: String?, apiVersion: String?): PsiElement? { fun PomFile.changeLanguageVersion(languageVersion: String?, apiVersion: String?): PsiElement? {
val kotlinPlugin = findPlugin(MavenId(KotlinMavenConfigurator.GROUP_ID, val kotlinPlugin = findPlugin(
MavenId(
KotlinMavenConfigurator.GROUP_ID,
KotlinMavenConfigurator.MAVEN_PLUGIN_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID,
null)) ?: return null null
)
) ?: return null
val languageElement = languageVersion?.let { val languageElement = languageVersion?.let {
changeConfigurationOrProperty(kotlinPlugin, "languageVersion", "kotlin.compiler.languageVersion", it) changeConfigurationOrProperty(kotlinPlugin, "languageVersion", "kotlin.compiler.languageVersion", it)
} }
@@ -598,9 +642,11 @@ fun PomFile.changeLanguageVersion(languageVersion: String?, apiVersion: String?)
return languageElement ?: apiElement return languageElement ?: apiElement
} }
private fun PomFile.changeConfigurationOrProperty(kotlinPlugin: MavenDomPlugin, private fun PomFile.changeConfigurationOrProperty(
kotlinPlugin: MavenDomPlugin,
configurationTagName: String, configurationTagName: String,
propertyName: String, value: String): XmlTag? { propertyName: String, value: String
): XmlTag? {
val configuration = kotlinPlugin.configuration val configuration = kotlinPlugin.configuration
if (configuration.exists()) { if (configuration.exists()) {
val subTag = configuration.xmlTag.findFirstSubTag(configurationTagName) val subTag = configuration.xmlTag.findFirstSubTag(configurationTagName)
@@ -623,8 +669,12 @@ private fun PomFile.changeConfigurationOrProperty(kotlinPlugin: MavenDomPlugin,
} }
fun PomFile.changeCoroutineConfiguration(value: String): PsiElement? { fun PomFile.changeCoroutineConfiguration(value: String): PsiElement? {
val kotlinPlugin = findPlugin(MavenId(KotlinMavenConfigurator.GROUP_ID, val kotlinPlugin = findPlugin(
MavenId(
KotlinMavenConfigurator.GROUP_ID,
KotlinMavenConfigurator.MAVEN_PLUGIN_ID, KotlinMavenConfigurator.MAVEN_PLUGIN_ID,
null)) ?: return null null
)
) ?: return null
return changeConfigurationOrProperty(kotlinPlugin, "experimentalCoroutines", "kotlin.compiler.experimental.coroutines", value) return changeConfigurationOrProperty(kotlinPlugin, "experimentalCoroutines", "kotlin.compiler.experimental.coroutines", value)
} }
@@ -110,7 +110,11 @@ class MavenPluginSourcesMoveToBuild : PsiElementBaseIntentionAction() {
} }
} }
private fun tryInvoke(project: Project, element: PsiElement, block: (pom: PomFile, dir: String, execution: MavenDomPluginExecution, build: MavenDomBuild) -> Unit = { _, _, _, _ -> }): Boolean { private fun tryInvoke(
project: Project,
element: PsiElement,
block: (pom: PomFile, dir: String, execution: MavenDomPluginExecution, build: MavenDomBuild) -> Unit = { _, _, _, _ -> }
): Boolean {
val file = element.containingFile val file = element.containingFile
if (file == null || !MavenDomUtil.isMavenFile(file) || (element !is XmlElement && element.parent !is XmlElement)) { if (file == null || !MavenDomUtil.isMavenFile(file) || (element !is XmlElement && element.parent !is XmlElement)) {
@@ -33,11 +33,15 @@ import org.jetbrains.kotlin.idea.maven.configuration.KotlinMavenConfigurator
import org.jetbrains.kotlin.idea.versions.MAVEN_STDLIB_ID import org.jetbrains.kotlin.idea.versions.MAVEN_STDLIB_ID
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
class GenerateMavenCompileExecutionAction : PomFileActionBase(KotlinMavenExecutionProvider(PomFile.KotlinGoals.Compile, PomFile.DefaultPhases.Compile)) class GenerateMavenCompileExecutionAction :
class GenerateMavenTestCompileExecutionAction : PomFileActionBase(KotlinMavenExecutionProvider(PomFile.KotlinGoals.TestCompile, PomFile.DefaultPhases.TestCompile)) PomFileActionBase(KotlinMavenExecutionProvider(PomFile.KotlinGoals.Compile, PomFile.DefaultPhases.Compile))
class GenerateMavenTestCompileExecutionAction :
PomFileActionBase(KotlinMavenExecutionProvider(PomFile.KotlinGoals.TestCompile, PomFile.DefaultPhases.TestCompile))
class GenerateMavenPluginAction : PomFileActionBase(KotlinMavenPluginProvider()) class GenerateMavenPluginAction : PomFileActionBase(KotlinMavenPluginProvider())
private val DefaultKotlinVersion = "\${kotlin.version}" private const val DefaultKotlinVersion = "\${kotlin.version}"
open class PomFileActionBase(generateProvider: AbstractDomGenerateProvider<*>) : GenerateDomElementAction(generateProvider) { open class PomFileActionBase(generateProvider: AbstractDomGenerateProvider<*>) : GenerateDomElementAction(generateProvider) {
override fun isValidForFile(project: Project, editor: Editor, file: PsiFile): Boolean { override fun isValidForFile(project: Project, editor: Editor, file: PsiFile): Boolean {
@@ -47,7 +51,8 @@ open class PomFileActionBase(generateProvider: AbstractDomGenerateProvider<*>) :
override fun startInWriteAction() = true override fun startInWriteAction() = true
} }
private class KotlinMavenPluginProvider : AbstractDomGenerateProvider<MavenDomPlugin>("kotlin-maven-plugin-provider", MavenDomPlugin::class.java) { private class KotlinMavenPluginProvider :
AbstractDomGenerateProvider<MavenDomPlugin>("kotlin-maven-plugin-provider", MavenDomPlugin::class.java) {
override fun generate(parent: DomElement?, editor: Editor?): MavenDomPlugin? { override fun generate(parent: DomElement?, editor: Editor?): MavenDomPlugin? {
if (parent !is MavenDomProjectModel) { if (parent !is MavenDomProjectModel) {
@@ -82,7 +87,8 @@ private class KotlinMavenPluginProvider : AbstractDomGenerateProvider<MavenDomPl
} }
} }
private class KotlinMavenExecutionProvider(val goal: String, val phase: String) : AbstractDomGenerateProvider<MavenDomPlugin>("kotlin-maven-execution-provider", MavenDomPlugin::class.java) { private class KotlinMavenExecutionProvider(val goal: String, val phase: String) :
AbstractDomGenerateProvider<MavenDomPlugin>("kotlin-maven-execution-provider", MavenDomPlugin::class.java) {
override fun generate(parent: DomElement?, editor: Editor?): MavenDomPlugin? { override fun generate(parent: DomElement?, editor: Editor?): MavenDomPlugin? {
if (parent !is MavenDomPlugin) { if (parent !is MavenDomPlugin) {
@@ -99,7 +105,7 @@ private class KotlinMavenExecutionProvider(val goal: String, val phase: String)
return parent return parent
} }
override fun getElementToNavigate(t: MavenDomPlugin?) = null override fun getElementToNavigate(t: MavenDomPlugin?): DomElement? = null
override fun getParentDomElement(project: Project?, editor: Editor?, file: PsiFile?): DomElement? { override fun getParentDomElement(project: Project?, editor: Editor?, file: PsiFile?): DomElement? {
if (project == null || editor == null || file == null) { if (project == null || editor == null || file == null) {
@@ -129,8 +135,11 @@ private fun Char.isRangeEnd() = this == ']' || this == ')'
private fun String.isRangeVersion() = length > 2 && this[0].isRangeStart() && last().isRangeEnd() private fun String.isRangeVersion() = length > 2 && this[0].isRangeStart() && last().isRangeEnd()
private fun DomElement.findProject(): MavenDomProjectModel? = this as? MavenDomProjectModel ?: DomUtil.getParentOfType(this, MavenDomProjectModel::class.java, true) private fun DomElement.findProject(): MavenDomProjectModel? =
private fun DomElement.findPlugin(): MavenDomPlugin? = this as? MavenDomPlugin ?: DomUtil.getParentOfType(this, MavenDomPlugin::class.java, true) this as? MavenDomProjectModel ?: DomUtil.getParentOfType(this, MavenDomProjectModel::class.java, true)
private fun DomElement.findPlugin(): MavenDomPlugin? =
this as? MavenDomPlugin ?: DomUtil.getParentOfType(this, MavenDomPlugin::class.java, true)
private fun MavenDomPlugin.isKotlinMavenPlugin() = groupId.stringValue == KotlinMavenConfigurator.GROUP_ID private fun MavenDomPlugin.isKotlinMavenPlugin() = groupId.stringValue == KotlinMavenConfigurator.GROUP_ID
&& artifactId.stringValue == KotlinMavenConfigurator.MAVEN_PLUGIN_ID && artifactId.stringValue == KotlinMavenConfigurator.MAVEN_PLUGIN_ID
@@ -29,7 +29,12 @@ import org.jetbrains.kotlin.idea.versions.getStdlibArtifactId
import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
class KotlinJavaMavenConfigurator : KotlinMavenConfigurator(KotlinJavaMavenConfigurator.TEST_LIB_ID, false, KotlinJavaMavenConfigurator.NAME, KotlinJavaMavenConfigurator.PRESENTABLE_TEXT) { class KotlinJavaMavenConfigurator : KotlinMavenConfigurator(
KotlinJavaMavenConfigurator.TEST_LIB_ID,
false,
KotlinJavaMavenConfigurator.NAME,
KotlinJavaMavenConfigurator.PRESENTABLE_TEXT
) {
override fun isKotlinModule(module: Module) = override fun isKotlinModule(module: Module) =
hasKotlinJvmRuntimeInScope(module) hasKotlinJvmRuntimeInScope(module)
@@ -66,8 +71,8 @@ class KotlinJavaMavenConfigurator : KotlinMavenConfigurator(KotlinJavaMavenConfi
get() = JvmPlatform get() = JvmPlatform
companion object { companion object {
private val NAME = "maven" private const val NAME = "maven"
val TEST_LIB_ID = "kotlin-test" const val TEST_LIB_ID = "kotlin-test"
private val PRESENTABLE_TEXT = "Maven" private const val PRESENTABLE_TEXT = "Maven"
} }
} }
@@ -24,7 +24,8 @@ import org.jetbrains.kotlin.idea.versions.MAVEN_JS_STDLIB_ID
import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.resolve.TargetPlatform import org.jetbrains.kotlin.resolve.TargetPlatform
class KotlinJavascriptMavenConfigurator : KotlinMavenConfigurator(null, false, KotlinJavascriptMavenConfigurator.NAME, KotlinJavascriptMavenConfigurator.PRESENTABLE_TEXT) { class KotlinJavascriptMavenConfigurator :
KotlinMavenConfigurator(null, false, KotlinJavascriptMavenConfigurator.NAME, KotlinJavascriptMavenConfigurator.PRESENTABLE_TEXT) {
override fun getStdlibArtifactId(module: Module, version: String) = MAVEN_JS_STDLIB_ID override fun getStdlibArtifactId(module: Module, version: String) = MAVEN_JS_STDLIB_ID
@@ -47,7 +48,7 @@ class KotlinJavascriptMavenConfigurator : KotlinMavenConfigurator(null, false, K
override fun getMinimumSupportedVersion() = "1.1.0" override fun getMinimumSupportedVersion() = "1.1.0"
companion object { companion object {
private val NAME = "js maven" private const val NAME = "js maven"
private val PRESENTABLE_TEXT = "Maven (JavaScript)" private const val PRESENTABLE_TEXT = "Maven (JavaScript)"
} }
} }
@@ -41,10 +41,12 @@ import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor import org.jetbrains.kotlin.idea.versions.LibraryJarDescriptor
abstract class KotlinMavenConfigurator abstract class KotlinMavenConfigurator
protected constructor(private val testArtifactId: String?, protected constructor(
private val testArtifactId: String?,
private val addJunit: Boolean, private val addJunit: Boolean,
override val name: String, override val name: String,
override val presentableText: String) : KotlinProjectConfigurator { override val presentableText: String
) : KotlinProjectConfigurator {
override fun getStatus(moduleSourceRootGroup: ModuleSourceRootGroup): ConfigureKotlinStatus { override fun getStatus(moduleSourceRootGroup: ModuleSourceRootGroup): ConfigureKotlinStatus {
val module = moduleSourceRootGroup.baseModule val module = moduleSourceRootGroup.baseModule
@@ -108,8 +110,7 @@ abstract class KotlinMavenConfigurator
if (file != null && canConfigureFile(file)) { if (file != null && canConfigureFile(file)) {
configureModule(module, file, dialog.kotlinVersion, collector) configureModule(module, file, dialog.kotlinVersion, collector)
OpenFileAction.openFile(file.virtualFile, project) OpenFileAction.openFile(file.virtualFile, project)
} } else {
else {
showErrorMessage(project, "Cannot find pom.xml for module " + module.name) showErrorMessage(project, "Cannot find pom.xml for module " + module.name)
} }
} }
@@ -144,7 +145,13 @@ abstract class KotlinMavenConfigurator
val pom = PomFile.forFileOrNull(file as XmlFile) ?: return false val pom = PomFile.forFileOrNull(file as XmlFile) ?: return false
pom.addProperty(KOTLIN_VERSION_PROPERTY, version) pom.addProperty(KOTLIN_VERSION_PROPERTY, version)
pom.addDependency(MavenId(GROUP_ID, getStdlibArtifactId(module, version), "\${$KOTLIN_VERSION_PROPERTY}"), MavenArtifactScope.COMPILE, null, false, null) pom.addDependency(
MavenId(GROUP_ID, getStdlibArtifactId(module, version), "\${$KOTLIN_VERSION_PROPERTY}"),
MavenArtifactScope.COMPILE,
null,
false,
null
)
if (testArtifactId != null) { if (testArtifactId != null) {
pom.addDependency(MavenId(GROUP_ID, testArtifactId, "\${$KOTLIN_VERSION_PROPERTY}"), MavenArtifactScope.TEST, null, false, null) pom.addDependency(MavenId(GROUP_ID, testArtifactId, "\${$KOTLIN_VERSION_PROPERTY}"), MavenArtifactScope.TEST, null, false, null)
} }
@@ -179,8 +186,8 @@ abstract class KotlinMavenConfigurator
executionId: String, executionId: String,
goalName: String, goalName: String,
module: Module, module: Module,
isTest: Boolean) { isTest: Boolean
) {
pomFile.addKotlinExecution(module, kotlinPlugin, executionId, PomFile.getPhase(false, isTest), isTest, listOf(goalName)) pomFile.addKotlinExecution(module, kotlinPlugin, executionId, PomFile.getPhase(false, isTest), isTest, listOf(goalName))
if (hasJavaFiles(module)) { if (hasJavaFiles(module)) {
@@ -200,7 +207,8 @@ abstract class KotlinMavenConfigurator
val pom = PomFile.forFileOrNull(psi) ?: return null val pom = PomFile.forFileOrNull(psi) ?: return null
return pom.changeLanguageVersion( return pom.changeLanguageVersion(
languageVersion, languageVersion,
apiVersion) apiVersion
)
} }
val runtimeUpdateRequired = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) }?.let { runtimeVersion -> val runtimeUpdateRequired = getRuntimeLibraryVersion(module)?.let { ApiVersion.parse(it) }?.let { runtimeVersion ->
@@ -208,25 +216,33 @@ abstract class KotlinMavenConfigurator
} ?: false } ?: false
if (runtimeUpdateRequired) { if (runtimeUpdateRequired) {
Messages.showErrorDialog(module.project, Messages.showErrorDialog(
module.project,
"This language feature requires version $requiredStdlibVersion or later of the Kotlin runtime library. " + "This language feature requires version $requiredStdlibVersion or later of the Kotlin runtime library. " +
"Please update the version in your build script.", "Please update the version in your build script.",
"Update Language Version") "Update Language Version"
)
return return
} }
val element = doUpdateMavenLanguageVersion() val element = doUpdateMavenLanguageVersion()
if (element == null) { if (element == null) {
Messages.showErrorDialog(module.project, Messages.showErrorDialog(
module.project,
"Failed to update.pom.xml. Please update the file manually.", "Failed to update.pom.xml. Please update the file manually.",
"Update Language Version") "Update Language Version"
} )
else { } else {
OpenFileDescriptor(module.project, element.containingFile.virtualFile, element.textRange.startOffset).navigate(true) OpenFileDescriptor(module.project, element.containingFile.virtualFile, element.textRange.startOffset).navigate(true)
} }
} }
override fun addLibraryDependency(module: Module, element: PsiElement, library: ExternalLibraryDescriptor, libraryJarDescriptors: List<LibraryJarDescriptor>) { override fun addLibraryDependency(
module: Module,
element: PsiElement,
library: ExternalLibraryDescriptor,
libraryJarDescriptors: List<LibraryJarDescriptor>
) {
val scope = OrderEntryFix.suggestScopeByLocation(module, element) val scope = OrderEntryFix.suggestScopeByLocation(module, element)
JavaProjectModelModificationService.getInstance(module.project).addDependency(module, library, scope) JavaProjectModelModificationService.getInstance(module.project).addDependency(module, library, scope)
} }
@@ -237,10 +253,12 @@ abstract class KotlinMavenConfigurator
val messageTitle = ChangeCoroutineSupportFix.getFixText(state) val messageTitle = ChangeCoroutineSupportFix.getFixText(state)
if (runtimeUpdateRequired) { if (runtimeUpdateRequired) {
Messages.showErrorDialog(module.project, Messages.showErrorDialog(
module.project,
"Coroutines support requires version 1.1 or later of the Kotlin runtime library. " + "Coroutines support requires version 1.1 or later of the Kotlin runtime library. " +
"Please update the version in your build script.", "Please update the version in your build script.",
messageTitle) messageTitle
)
return return
} }
@@ -261,19 +279,19 @@ abstract class KotlinMavenConfigurator
val element = doChangeMavenCoroutineConfiguration() val element = doChangeMavenCoroutineConfiguration()
if (element == null) { if (element == null) {
Messages.showErrorDialog(module.project, Messages.showErrorDialog(
module.project,
"Failed to update.pom.xml. Please update the file manually.", "Failed to update.pom.xml. Please update the file manually.",
messageTitle) messageTitle
)
} }
return element return element
} }
companion object { companion object {
val NAME = "maven" const val GROUP_ID = "org.jetbrains.kotlin"
const val MAVEN_PLUGIN_ID = "kotlin-maven-plugin"
val GROUP_ID = "org.jetbrains.kotlin" private const val KOTLIN_VERSION_PROPERTY = "kotlin.version"
val MAVEN_PLUGIN_ID = "kotlin-maven-plugin"
private val KOTLIN_VERSION_PROPERTY = "kotlin.version"
private fun hasJavaFiles(module: Module): Boolean { private fun hasJavaFiles(module: Module): Boolean {
return !FileTypeIndex.getFiles(JavaFileType.INSTANCE, GlobalSearchScope.moduleScope(module)).isEmpty() return !FileTypeIndex.getFiles(JavaFileType.INSTANCE, GlobalSearchScope.moduleScope(module)).isEmpty()
@@ -296,11 +314,13 @@ abstract class KotlinMavenConfigurator
} }
private fun showErrorMessage(project: Project, message: String?) { private fun showErrorMessage(project: Project, message: String?) {
Messages.showErrorDialog(project, Messages.showErrorDialog(
project,
"<html>Couldn't configure kotlin-maven plugin automatically.<br/>" + "<html>Couldn't configure kotlin-maven plugin automatically.<br/>" +
(if (message != null) "$message</br>" else "") + (if (message != null) "$message</br>" else "") +
"See manual installation instructions <a href=\"http://confluence.jetbrains.com/display/Kotlin/Kotlin+Build+Tools#KotlinBuildTools-Maven\">here</a>.</html>", "See manual installation instructions <a href=\"http://confluence.jetbrains.com/display/Kotlin/Kotlin+Build+Tools#KotlinBuildTools-Maven\">here</a>.</html>",
"Configure Kotlin-Maven Plugin") "Configure Kotlin-Maven Plugin"
)
} }
} }
} }
@@ -43,7 +43,8 @@ class DeprecatedMavenDependencyInspection : DomElementsInspection<MavenDomProjec
pomFile.findDependencies(MavenId(libInfo.old.groupId, libInfo.old.name, null)) pomFile.findDependencies(MavenId(libInfo.old.groupId, libInfo.old.name, null))
.filter { it.version?.stringValue != null } .filter { it.version?.stringValue != null }
.filter { .filter {
val libVersion = project.findDependencies(libInfo.old.groupId, libInfo.old.name).map { it.version }.distinct().singleOrNull() val libVersion =
project.findDependencies(libInfo.old.groupId, libInfo.old.name).map { it.version }.distinct().singleOrNull()
libVersion != null && VersionComparatorUtil.COMPARATOR.compare(libVersion, libInfo.outdatedAfterVersion) >= 0 libVersion != null && VersionComparatorUtil.COMPARATOR.compare(libVersion, libInfo.outdatedAfterVersion) >= 0
} }
.forEach { dependency -> .forEach { dependency ->
@@ -51,11 +52,13 @@ class DeprecatedMavenDependencyInspection : DomElementsInspection<MavenDomProjec
if (xmlElement != null) { if (xmlElement != null) {
val fix = ReplaceStringInDocumentFix(xmlElement, libInfo.old.name, libInfo.new.name) val fix = ReplaceStringInDocumentFix(xmlElement, libInfo.old.name, libInfo.new.name)
holder.createProblem(dependency.artifactId, holder.createProblem(
dependency.artifactId,
ProblemHighlightType.LIKE_DEPRECATED, ProblemHighlightType.LIKE_DEPRECATED,
libInfo.message, libInfo.message,
null, null,
fix) fix
)
} }
} }
} }
@@ -28,7 +28,8 @@ import org.jetbrains.kotlin.idea.inspections.PluginVersionDependentInspection
import org.jetbrains.kotlin.idea.maven.PomFile import org.jetbrains.kotlin.idea.maven.PomFile
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
class DifferentKotlinMavenVersionInspection : DomElementsInspection<MavenDomProjectModel>(MavenDomProjectModel::class.java), PluginVersionDependentInspection { class DifferentKotlinMavenVersionInspection : DomElementsInspection<MavenDomProjectModel>(MavenDomProjectModel::class.java),
PluginVersionDependentInspection {
private val idePluginVersion by lazy { bundledRuntimeVersion() } private val idePluginVersion by lazy { bundledRuntimeVersion() }
override var testVersionMessage: String? = null override var testVersionMessage: String? = null
@@ -53,8 +54,11 @@ class DifferentKotlinMavenVersionInspection : DomElementsInspection<MavenDomProj
} }
private fun createProblem(holder: DomElementAnnotationHolder, plugin: MavenDomPlugin) { private fun createProblem(holder: DomElementAnnotationHolder, plugin: MavenDomPlugin) {
holder.createProblem(plugin.version, holder.createProblem(
plugin.version,
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"Kotlin version that is used for building with Maven (${plugin.version.stringValue}) differs from the one bundled into the IDE plugin (${testVersionMessage ?: idePluginVersion})") "Kotlin version that is used for building with Maven (${plugin.version.stringValue}) differs from the one bundled into the IDE plugin (${testVersionMessage
?: idePluginVersion})"
)
} }
} }
@@ -57,7 +57,8 @@ class DifferentMavenStdlibVersionInspection : DomElementsInspection<MavenDomProj
createFixes(project, plugin.version, stdlibVersion + version) createFixes(project, plugin.version, stdlibVersion + version)
} ?: emptyList() } ?: emptyList()
holder.createProblem(plugin.version, holder.createProblem(
plugin.version,
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"Plugin version (${plugin.version}) is not the same as library version (${stdlibVersion.joinToString(",", "", "")})", "Plugin version (${plugin.version}) is not the same as library version (${stdlibVersion.joinToString(",", "", "")})",
*fixes.toTypedArray() *fixes.toTypedArray()
@@ -71,10 +72,12 @@ class DifferentMavenStdlibVersionInspection : DomElementsInspection<MavenDomProj
createFixes(project, dependency.version, listOf(version, pluginVersion)) createFixes(project, dependency.version, listOf(version, pluginVersion))
} ?: emptyList() } ?: emptyList()
holder.createProblem(dependency.version, holder.createProblem(
dependency.version,
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"Plugin version ($pluginVersion) is not the same as library version (${dependency.version})", "Plugin version ($pluginVersion) is not the same as library version (${dependency.version})",
*fixes.toTypedArray()) *fixes.toTypedArray()
)
} }
} }
@@ -90,8 +93,11 @@ class DifferentMavenStdlibVersionInspection : DomElementsInspection<MavenDomProj
SetVersionQuickFix(versionElement, bestVersion, null) SetVersionQuickFix(versionElement, bestVersion, null)
} }
private class SetVersionQuickFix(val versionElement: GenericDomValue<*>, val newVersion: String, val versionResolved: String?) : LocalQuickFix { private class SetVersionQuickFix(val versionElement: GenericDomValue<*>, val newVersion: String, val versionResolved: String?) :
override fun getName() = if (versionResolved == null) "Change version to $newVersion" else "Change version to $newVersion ($versionResolved)" LocalQuickFix {
override fun getName() =
if (versionResolved == null) "Change version to $newVersion" else "Change version to $newVersion ($versionResolved)"
override fun getFamilyName() = "Change version" override fun getFamilyName() = "Change version"
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@@ -71,20 +71,23 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
if (PomFile.KotlinGoals.Compile !in allGoalsSet && PomFile.KotlinGoals.Js !in allGoalsSet) { if (PomFile.KotlinGoals.Compile !in allGoalsSet && PomFile.KotlinGoals.Js !in allGoalsSet) {
val fixes = if (hasJavaFiles) { val fixes = if (hasJavaFiles) {
arrayOf(AddExecutionLocalFix(domFileElement.file, module, kotlinPlugin, PomFile.KotlinGoals.Compile)) arrayOf(AddExecutionLocalFix(domFileElement.file, module, kotlinPlugin, PomFile.KotlinGoals.Compile))
} } else {
else { arrayOf(
arrayOf(AddExecutionLocalFix(domFileElement.file, module, kotlinPlugin, PomFile.KotlinGoals.Compile), AddExecutionLocalFix(domFileElement.file, module, kotlinPlugin, PomFile.KotlinGoals.Compile),
AddExecutionLocalFix(domFileElement.file, module, kotlinPlugin, PomFile.KotlinGoals.Js)) AddExecutionLocalFix(domFileElement.file, module, kotlinPlugin, PomFile.KotlinGoals.Js)
)
} }
holder.createProblem(kotlinPlugin.artifactId.createStableCopy(), holder.createProblem(
kotlinPlugin.artifactId.createStableCopy(),
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"Kotlin plugin has no compile executions", "Kotlin plugin has no compile executions",
*fixes) *fixes
} )
else { } else {
if (hasJavaFiles) { if (hasJavaFiles) {
pom.findExecutions(kotlinPlugin, PomFile.KotlinGoals.Compile).notAtPhase(PomFile.DefaultPhases.ProcessSources).forEach { badExecution -> pom.findExecutions(kotlinPlugin, PomFile.KotlinGoals.Compile).notAtPhase(PomFile.DefaultPhases.ProcessSources)
.forEach { badExecution ->
val javacPlugin = mavenProject.findPlugin("org.apache.maven.plugins", "maven-compiler-plugin") val javacPlugin = mavenProject.findPlugin("org.apache.maven.plugins", "maven-compiler-plugin")
val existingJavac = pom.domModel.build.plugins.plugins.firstOrNull { val existingJavac = pom.domModel.build.plugins.plugins.firstOrNull {
it.groupId.stringValue == "org.apache.maven.plugins" && it.groupId.stringValue == "org.apache.maven.plugins" &&
@@ -98,18 +101,22 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
|| pom.isPluginExecutionMissing(javacPlugin, "default-compile", "compile") || pom.isPluginExecutionMissing(javacPlugin, "default-compile", "compile")
|| pom.isPluginExecutionMissing(javacPlugin, "default-testCompile", "testCompile")) { || pom.isPluginExecutionMissing(javacPlugin, "default-testCompile", "testCompile")) {
holder.createProblem(badExecution.phase.createStableCopy(), holder.createProblem(
badExecution.phase.createStableCopy(),
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"Kotlin plugin should run before javac so kotlin classes could be visible from Java", "Kotlin plugin should run before javac so kotlin classes could be visible from Java",
FixExecutionPhaseLocalFix(badExecution, PomFile.DefaultPhases.ProcessSources), FixExecutionPhaseLocalFix(badExecution, PomFile.DefaultPhases.ProcessSources),
AddJavaExecutionsLocalFix(module, domFileElement.file, kotlinPlugin)) AddJavaExecutionsLocalFix(module, domFileElement.file, kotlinPlugin)
)
} }
} }
pom.findExecutions(kotlinPlugin, PomFile.KotlinGoals.Js, PomFile.KotlinGoals.TestJs).forEach { badExecution -> pom.findExecutions(kotlinPlugin, PomFile.KotlinGoals.Js, PomFile.KotlinGoals.TestJs).forEach { badExecution ->
holder.createProblem(badExecution.goals.goals.first { it.isJsGoal() }.createStableCopy(), holder.createProblem(
badExecution.goals.goals.first { it.isJsGoal() }.createStableCopy(),
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"JavaScript goal configured for module with Java files") "JavaScript goal configured for module with Java files"
)
} }
} }
@@ -117,16 +124,20 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
val jsDependencies = mavenProject.findDependencies(KotlinMavenConfigurator.GROUP_ID, MAVEN_JS_STDLIB_ID) val jsDependencies = mavenProject.findDependencies(KotlinMavenConfigurator.GROUP_ID, MAVEN_JS_STDLIB_ID)
if (hasJvmExecution && stdlibDependencies.isEmpty()) { if (hasJvmExecution && stdlibDependencies.isEmpty()) {
holder.createProblem(kotlinPlugin.artifactId.createStableCopy(), holder.createProblem(
kotlinPlugin.artifactId.createStableCopy(),
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"Kotlin JVM compiler configured but no $MAVEN_STDLIB_ID dependency", "Kotlin JVM compiler configured but no $MAVEN_STDLIB_ID dependency",
FixAddStdlibLocalFix(domFileElement.file, MAVEN_STDLIB_ID, kotlinPlugin.version.rawText)) FixAddStdlibLocalFix(domFileElement.file, MAVEN_STDLIB_ID, kotlinPlugin.version.rawText)
)
} }
if (hasJsExecution && jsDependencies.isEmpty()) { if (hasJsExecution && jsDependencies.isEmpty()) {
holder.createProblem(kotlinPlugin.artifactId.createStableCopy(), holder.createProblem(
kotlinPlugin.artifactId.createStableCopy(),
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"Kotlin JavaScript compiler configured but no $MAVEN_JS_STDLIB_ID dependency", "Kotlin JavaScript compiler configured but no $MAVEN_JS_STDLIB_ID dependency",
FixAddStdlibLocalFix(domFileElement.file, MAVEN_JS_STDLIB_ID, kotlinPlugin.version.rawText)) FixAddStdlibLocalFix(domFileElement.file, MAVEN_JS_STDLIB_ID, kotlinPlugin.version.rawText)
)
} }
} }
} }
@@ -134,20 +145,24 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
val stdlibDependencies = pom.findDependencies(MavenId(KotlinMavenConfigurator.GROUP_ID, MAVEN_STDLIB_ID, null)) val stdlibDependencies = pom.findDependencies(MavenId(KotlinMavenConfigurator.GROUP_ID, MAVEN_STDLIB_ID, null))
if (!hasJvmExecution && stdlibDependencies.isNotEmpty()) { if (!hasJvmExecution && stdlibDependencies.isNotEmpty()) {
stdlibDependencies.forEach { dep -> stdlibDependencies.forEach { dep ->
holder.createProblem(dep.artifactId.createStableCopy(), holder.createProblem(
dep.artifactId.createStableCopy(),
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"You have ${dep.artifactId} configured but no corresponding plugin execution", "You have ${dep.artifactId} configured but no corresponding plugin execution",
ConfigurePluginExecutionLocalFix(module, domFileElement.file, PomFile.KotlinGoals.Compile, dep.version.rawText)) ConfigurePluginExecutionLocalFix(module, domFileElement.file, PomFile.KotlinGoals.Compile, dep.version.rawText)
)
} }
} }
val stdlibJsDependencies = pom.findDependencies(MavenId(KotlinMavenConfigurator.GROUP_ID, MAVEN_JS_STDLIB_ID, null)) val stdlibJsDependencies = pom.findDependencies(MavenId(KotlinMavenConfigurator.GROUP_ID, MAVEN_JS_STDLIB_ID, null))
if (!hasJsExecution && stdlibJsDependencies.isNotEmpty()) { if (!hasJsExecution && stdlibJsDependencies.isNotEmpty()) {
stdlibJsDependencies.forEach { dep -> stdlibJsDependencies.forEach { dep ->
holder.createProblem(dep.artifactId.createStableCopy(), holder.createProblem(
dep.artifactId.createStableCopy(),
HighlightSeverity.WARNING, HighlightSeverity.WARNING,
"You have ${dep.artifactId} configured but no corresponding plugin execution", "You have ${dep.artifactId} configured but no corresponding plugin execution",
ConfigurePluginExecutionLocalFix(module, domFileElement.file, PomFile.KotlinGoals.Js, dep.version.rawText)) ConfigurePluginExecutionLocalFix(module, domFileElement.file, PomFile.KotlinGoals.Js, dep.version.rawText)
)
} }
} }
@@ -155,19 +170,23 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
it.goals.goals.any { it.rawText == PomFile.KotlinGoals.Compile || it.rawText == PomFile.KotlinGoals.Js } it.goals.goals.any { it.rawText == PomFile.KotlinGoals.Compile || it.rawText == PomFile.KotlinGoals.Js }
&& it.goals.goals.any { it.rawText == PomFile.KotlinGoals.TestCompile || it.rawText == PomFile.KotlinGoals.TestJs } && it.goals.goals.any { it.rawText == PomFile.KotlinGoals.TestCompile || it.rawText == PomFile.KotlinGoals.TestJs }
}.forEach { badExecution -> }.forEach { badExecution ->
holder.createProblem(badExecution.goals.createStableCopy(), holder.createProblem(
badExecution.goals.createStableCopy(),
HighlightSeverity.WEAK_WARNING, HighlightSeverity.WEAK_WARNING,
"It is not recommended to have both test and compile goals in the same execution") "It is not recommended to have both test and compile goals in the same execution"
)
} }
} }
private class AddExecutionLocalFix(val file: XmlFile, val module: Module, val kotlinPlugin: MavenDomPlugin, val goal: String) : LocalQuickFix { private class AddExecutionLocalFix(val file: XmlFile, val module: Module, val kotlinPlugin: MavenDomPlugin, val goal: String) :
LocalQuickFix {
override fun getName() = "Create $goal execution" override fun getName() = "Create $goal execution"
override fun getFamilyName() = "Create kotlin execution" override fun getFamilyName() = "Create kotlin execution"
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
PomFile.forFileOrNull(file)?.addKotlinExecution(module, kotlinPlugin, goal, PomFile.getPhase(module.hasJavaFiles(), false), false, listOf(goal)) PomFile.forFileOrNull(file)
?.addKotlinExecution(module, kotlinPlugin, goal, PomFile.getPhase(module.hasJavaFiles(), false), false, listOf(goal))
} }
} }
@@ -195,11 +214,13 @@ class KotlinMavenPluginPhaseInspection : DomElementsInspection<MavenDomProjectMo
override fun getFamilyName() = "Add dependency" override fun getFamilyName() = "Add dependency"
override fun applyFix(project: Project, descriptor: ProblemDescriptor) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
PomFile.forFileOrNull(pomFile)?.addDependency(MavenId(KotlinMavenConfigurator.GROUP_ID, id, version), MavenArtifactScope.COMPILE) PomFile.forFileOrNull(pomFile)
?.addDependency(MavenId(KotlinMavenConfigurator.GROUP_ID, id, version), MavenArtifactScope.COMPILE)
} }
} }
private class ConfigurePluginExecutionLocalFix(val module: Module, val xmlFile: XmlFile, val goal: String, val version: String?) : LocalQuickFix { private class ConfigurePluginExecutionLocalFix(val module: Module, val xmlFile: XmlFile, val goal: String, val version: String?) :
LocalQuickFix {
override fun getName() = "Create $goal execution of kotlin-maven-compiler" override fun getName() = "Create $goal execution of kotlin-maven-compiler"
override fun getFamilyName() = "Create kotlin execution" override fun getFamilyName() = "Create kotlin execution"
@@ -59,8 +59,7 @@ class KotlinMavenUnresolvedReferenceQuickFixProvider : UnresolvedReferenceQuickF
} else { } else {
importDirective.importedFqName?.asString() importDirective.importedFqName?.asString()
} }
} } else {
else {
val typeReference = expression.getParentOfType<KtTypeReference>(true) val typeReference = expression.getParentOfType<KtTypeReference>(true)
val referenced = typeReference?.text ?: expression.getReferencedName() val referenced = typeReference?.text ?: expression.getReferencedName()
@@ -77,7 +76,11 @@ class KotlinMavenUnresolvedReferenceQuickFixProvider : UnresolvedReferenceQuickF
} }
} }
class AddMavenDependencyQuickFix(val className: String, val smartPsiElementPointer: SmartPsiElementPointer<KtSimpleNameExpression>) : IntentionAction, LowPriorityAction { class AddMavenDependencyQuickFix(
val className: String,
private val smartPsiElementPointer: SmartPsiElementPointer<KtSimpleNameExpression>
) :
IntentionAction, LowPriorityAction {
override fun getText() = "Add Maven dependency..." override fun getText() = "Add Maven dependency..."
override fun getFamilyName() = text override fun getFamilyName() = text
override fun startInWriteAction() = false override fun startInWriteAction() = false
@@ -48,7 +48,8 @@ class KotlinTestJUnitInspection : DomElementsInspection<MavenDomProjectModel>(Ma
.dependencies.filter { it.groupId.rawText == KotlinMavenConfigurator.GROUP_ID && it.artifactId.rawText == KotlinJavaMavenConfigurator.TEST_LIB_ID } .dependencies.filter { it.groupId.rawText == KotlinMavenConfigurator.GROUP_ID && it.artifactId.rawText == KotlinJavaMavenConfigurator.TEST_LIB_ID }
kotlinTestDependencies.forEach { kotlinTestDependencies.forEach {
holder.createProblem(it.artifactId, holder.createProblem(
it.artifactId,
HighlightSeverity.WEAK_WARNING, HighlightSeverity.WEAK_WARNING,
"kotlin-test-junit is better with junit", "kotlin-test-junit is better with junit",
ReplaceToKotlinTest(it) ReplaceToKotlinTest(it)
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.idea.maven
import com.intellij.codeInspection.CommonProblemDescriptor import com.intellij.codeInspection.CommonProblemDescriptor
import com.intellij.codeInspection.ProblemDescriptorBase import com.intellij.codeInspection.ProblemDescriptorBase
import com.intellij.codeInspection.QuickFix import com.intellij.codeInspection.QuickFix
import com.intellij.codeInspection.reference.RefEntity
import com.intellij.ide.highlighter.JavaFileType import com.intellij.ide.highlighter.JavaFileType
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.Result import com.intellij.openapi.application.Result
@@ -60,11 +59,13 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() {
mkJavaFile() mkJavaFile()
} }
val inspectionClassName = "<!--\\s*inspection:\\s*([\\S]+)\\s-->".toRegex().find(pomText)?.groups?.get(1)?.value ?: KotlinMavenPluginPhaseInspection::class.qualifiedName !! val inspectionClassName = "<!--\\s*inspection:\\s*([\\S]+)\\s-->".toRegex().find(pomText)?.groups?.get(1)?.value
?: KotlinMavenPluginPhaseInspection::class.qualifiedName!!
val inspectionClass = Class.forName(inspectionClassName) val inspectionClass = Class.forName(inspectionClassName)
val matcher = "<!--\\s*problem:\\s*on\\s*([^,]+),\\s*title\\s*(.+)\\s*-->".toRegex() val matcher = "<!--\\s*problem:\\s*on\\s*([^,]+),\\s*title\\s*(.+)\\s*-->".toRegex()
val expected = pomText.lines().mapNotNull { matcher.find(it) }.map { SimplifiedProblemDescription(it.groups[2]!!.value.trim(), it.groups[1]!!.value.trim()) } val expected = pomText.lines().mapNotNull { matcher.find(it) }
.map { SimplifiedProblemDescription(it.groups[2]!!.value.trim(), it.groups[1]!!.value.trim()) }
val problemElements = runInspection(inspectionClass, myProject).problemElements val problemElements = runInspection(inspectionClass, myProject).problemElements
val actualProblems = problemElements val actualProblems = problemElements
.keys() .keys()
@@ -82,7 +83,8 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() {
val suggestedFixes = actual.flatMap { p -> p.second.fixes?.sortedBy { it.familyName }?.map { p.second to it } ?: emptyList() } val suggestedFixes = actual.flatMap { p -> p.second.fixes?.sortedBy { it.familyName }?.map { p.second to it } ?: emptyList() }
val filenamePrefix = pomFile.nameWithoutExtension + ".fixed." val filenamePrefix = pomFile.nameWithoutExtension + ".fixed."
val fixFiles = pomFile.parentFile.listFiles { _, name -> name.startsWith(filenamePrefix) && name.endsWith(".xml") }.sortedBy { it.name } val fixFiles =
pomFile.parentFile.listFiles { _, name -> name.startsWith(filenamePrefix) && name.endsWith(".xml") }.sortedBy { it.name }
if (fixFiles.size > suggestedFixes.size) { if (fixFiles.size > suggestedFixes.size) {
fail("Not all fixes were suggested by the inspection: expected count: ${fixFiles.size}, actual fixes count: ${suggestedFixes.size}") fail("Not all fixes were suggested by the inspection: expected count: ${fixFiles.size}, actual fixes count: ${suggestedFixes.size}")
@@ -144,7 +146,8 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() {
} }
private fun mkJavaFile() { private fun mkJavaFile() {
val sourceFolder = getContentRoots(myProject.allModules().single().name).single().getSourceFolders(JavaSourceRootType.SOURCE).single() val sourceFolder =
getContentRoots(myProject.allModules().single().name).single().getSourceFolders(JavaSourceRootType.SOURCE).single()
ApplicationManager.getApplication().runWriteAction { ApplicationManager.getApplication().runWriteAction {
val javaFile = sourceFolder.file?.toPsiDirectory(myProject)?.createFile("Test.java") ?: throw IllegalStateException() val javaFile = sourceFolder.file?.toPsiDirectory(myProject)?.createFile("Test.java") ?: throw IllegalStateException()
javaFile.viewProvider.document!!.setText("class Test {}\n") javaFile.viewProvider.document!!.setText("class Test {}\n")
@@ -24,7 +24,9 @@ import org.junit.Test
import java.io.File import java.io.File
class KotlinMavenArchetypesProviderTest { class KotlinMavenArchetypesProviderTest {
private val BASE_PATH = "idea/testData/configuration/" companion object {
private const val BASE_PATH = "idea/testData/configuration/"
}
@Test @Test
fun extractVersions() { fun extractVersions() {
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
import org.jetbrains.kotlin.idea.framework.JSLibraryKind import org.jetbrains.kotlin.idea.framework.JSLibraryKind
import org.jetbrains.kotlin.idea.refactoring.toPsiFile import org.jetbrains.kotlin.idea.refactoring.toPsiFile
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.config.LanguageVersion
import org.junit.Assert import org.junit.Assert
import java.io.File import java.io.File
@@ -47,7 +46,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
} }
fun testSimpleKotlinProject() { fun testSimpleKotlinProject() {
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -59,7 +59,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
<version>$kotlinVersion</version> <version>$kotlinVersion</version>
</dependency> </dependency>
</dependencies> </dependencies>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -69,7 +70,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testWithSpecifiedSourceRoot() { fun testWithSpecifiedSourceRoot() {
createProjectSubDir("src/main/kotlin") createProjectSubDir("src/main/kotlin")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -85,7 +87,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
<build> <build>
<sourceDirectory>src/main/kotlin</sourceDirectory> <sourceDirectory>src/main/kotlin</sourceDirectory>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -95,7 +98,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testWithCustomSourceDirs() { fun testWithCustomSourceDirs() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -148,7 +152,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -160,7 +165,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testReImportRemoveDir() { fun testReImportRemoveDir() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -213,7 +219,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -222,7 +229,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm") assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm")
// reimport // reimport
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -274,7 +282,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertSources("project", "src/main/kotlin") assertSources("project", "src/main/kotlin")
assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm") assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm")
@@ -283,7 +292,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testReImportAddDir() { fun testReImportAddDir() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -335,7 +345,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -344,7 +355,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm") assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm")
// reimport // reimport
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -397,7 +409,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertSources("project", "src/main/kotlin", "src/main/kotlin.jvm") assertSources("project", "src/main/kotlin", "src/main/kotlin.jvm")
assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm") assertTestSources("project", "src/test/java", "src/test/kotlin", "src/test/kotlin.jvm")
@@ -406,7 +419,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJvmFacetConfiguration() { fun testJvmFacetConfiguration() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -450,7 +464,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -467,15 +482,18 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
Assert.assertEquals("JVM 1.8", targetPlatformKind!!.description) Assert.assertEquals("JVM 1.8", targetPlatformKind!!.description)
Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget) Assert.assertEquals("1.8", (compilerArguments as K2JVMCompilerArguments).jvmTarget)
Assert.assertEquals("foobar.jar", (compilerArguments as K2JVMCompilerArguments).classpath) Assert.assertEquals("foobar.jar", (compilerArguments as K2JVMCompilerArguments).classpath)
Assert.assertEquals("-Xmulti-platform", Assert.assertEquals(
compilerSettings!!.additionalArguments) "-Xmulti-platform",
compilerSettings!!.additionalArguments
)
} }
} }
fun testJvmFacetConfigurationFromProperties() { fun testJvmFacetConfigurationFromProperties() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -514,7 +532,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -532,7 +551,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJsFacetConfiguration() { fun testJsFacetConfiguration() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -578,7 +598,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -592,13 +613,15 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
Assert.assertFalse(compilerArguments!!.autoAdvanceApiVersion) Assert.assertFalse(compilerArguments!!.autoAdvanceApiVersion)
Assert.assertEquals(true, compilerArguments!!.suppressWarnings) Assert.assertEquals(true, compilerArguments!!.suppressWarnings)
Assert.assertEquals(LanguageFeature.State.ENABLED, coroutineSupport) Assert.assertEquals(LanguageFeature.State.ENABLED, coroutineSupport)
Assert.assertTrue(targetPlatformKind is TargetPlatformKind.JavaScript) Assert.assertTrue(targetPlatformKind == TargetPlatformKind.JavaScript)
with(compilerArguments as K2JSCompilerArguments) { with(compilerArguments as K2JSCompilerArguments) {
Assert.assertEquals(true, sourceMap) Assert.assertEquals(true, sourceMap)
Assert.assertEquals("commonjs", moduleKind) Assert.assertEquals("commonjs", moduleKind)
} }
Assert.assertEquals("-meta-info -output test.js -Xmulti-platform", Assert.assertEquals(
compilerSettings!!.additionalArguments) "-meta-info -output test.js -Xmulti-platform",
compilerSettings!!.additionalArguments
)
} }
val rootManager = ModuleRootManager.getInstance(getModule("project")) val rootManager = ModuleRootManager.getInstance(getModule("project"))
@@ -609,7 +632,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testFacetSplitConfiguration() { fun testFacetSplitConfiguration() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -655,7 +679,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -677,7 +702,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testArgsInFacet() { fun testArgsInFacet() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -719,7 +745,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -735,7 +762,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testArgsInFacetInSingleElement() { fun testArgsInFacetInSingleElement() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -773,7 +801,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -789,7 +818,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJvmDetectionByGoalWithJvmStdlib() { fun testJvmDetectionByGoalWithJvmStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -826,7 +856,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -837,7 +868,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJvmDetectionByGoalWithJsStdlib() { fun testJvmDetectionByGoalWithJsStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -874,7 +906,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -885,7 +918,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJvmDetectionByGoalWithCommonStdlib() { fun testJvmDetectionByGoalWithCommonStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -922,7 +956,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -933,7 +968,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJsDetectionByGoalWithJvmStdlib() { fun testJsDetectionByGoalWithJvmStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -970,7 +1006,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -981,7 +1018,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJsDetectionByGoalWithJsStdlib() { fun testJsDetectionByGoalWithJsStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1018,7 +1056,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1029,7 +1068,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJsDetectionByGoalWithCommonStdlib() { fun testJsDetectionByGoalWithCommonStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1066,7 +1106,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1077,7 +1118,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJsAndCommonStdlibKinds() { fun testJsAndCommonStdlibKinds() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1119,7 +1161,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1127,7 +1170,7 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind) Assert.assertEquals(TargetPlatformKind.JavaScript, facetSettings.targetPlatformKind)
val rootManager = ModuleRootManager.getInstance(getModule("project")) val rootManager = ModuleRootManager.getInstance(getModule("project"))
val libraries = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().mapNotNull { it.library as LibraryEx } val libraries = rootManager.orderEntries.filterIsInstance<LibraryOrderEntry>().map { it.library as LibraryEx }
assertEquals(JSLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-js") == true }.kind) assertEquals(JSLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-js") == true }.kind)
assertEquals(CommonLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-common") == true }.kind) assertEquals(CommonLibraryKind, libraries.single { it.name?.contains("kotlin-stdlib-common") == true }.kind)
} }
@@ -1135,7 +1178,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testCommonDetectionByGoalWithJvmStdlib() { fun testCommonDetectionByGoalWithJvmStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1166,7 +1210,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1177,7 +1222,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testCommonDetectionByGoalWithJsStdlib() { fun testCommonDetectionByGoalWithJsStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1208,7 +1254,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1219,7 +1266,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testCommonDetectionByGoalWithCommonStdlib() { fun testCommonDetectionByGoalWithCommonStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId>0 <groupId>test</groupId>0
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1250,7 +1298,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1265,7 +1314,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJvmDetectionByConflictingGoalsAndJvmStdlib() { fun testJvmDetectionByConflictingGoalsAndJvmStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1302,7 +1352,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1313,7 +1364,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testJsDetectionByConflictingGoalsAndJsStdlib() { fun testJsDetectionByConflictingGoalsAndJsStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1350,7 +1402,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1361,7 +1414,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testCommonDetectionByConflictingGoalsAndCommonStdlib() { fun testCommonDetectionByConflictingGoalsAndCommonStdlib() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1398,7 +1452,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1409,7 +1464,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testNoPluginsInAdditionalArgs() { fun testNoPluginsInAdditionalArgs() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1454,7 +1510,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1465,12 +1522,14 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
compilerSettings!!.additionalArguments compilerSettings!!.additionalArguments
) )
Assert.assertEquals( Assert.assertEquals(
listOf("plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.stereotype.Component", listOf(
"plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.stereotype.Component",
"plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.transaction.annotation.Transactional", "plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.transaction.annotation.Transactional",
"plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.scheduling.annotation.Async", "plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.scheduling.annotation.Async",
"plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.cache.annotation.Cacheable", "plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.cache.annotation.Cacheable",
"plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.boot.test.context.SpringBootTest", "plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.boot.test.context.SpringBootTest",
"plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.validation.annotation.Validated"), "plugin:org.jetbrains.kotlin.allopen:annotation=org.springframework.validation.annotation.Validated"
),
compilerArguments!!.pluginOptions!!.toList() compilerArguments!!.pluginOptions!!.toList()
) )
} }
@@ -1479,7 +1538,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testNoArgInvokeInitializers() { fun testNoArgInvokeInitializers() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1529,7 +1589,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1540,8 +1601,10 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
compilerSettings!!.additionalArguments compilerSettings!!.additionalArguments
) )
Assert.assertEquals( Assert.assertEquals(
listOf("plugin:org.jetbrains.kotlin.noarg:annotation=NoArg", listOf(
"plugin:org.jetbrains.kotlin.noarg:invokeInitializers=true"), "plugin:org.jetbrains.kotlin.noarg:annotation=NoArg",
"plugin:org.jetbrains.kotlin.noarg:invokeInitializers=true"
),
compilerArguments!!.pluginOptions!!.toList() compilerArguments!!.pluginOptions!!.toList()
) )
} }
@@ -1550,7 +1613,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testArgsOverridingInFacet() { fun testArgsOverridingInFacet() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1596,7 +1660,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -1612,7 +1677,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testSubmoduleArgsInheritance() { fun testSubmoduleArgsInheritance() {
createProjectSubDirs("src/main/kotlin", "myModule1/src/main/kotlin", "myModule2/src/main/kotlin", "myModule3/src/main/kotlin") createProjectSubDirs("src/main/kotlin", "myModule1/src/main/kotlin", "myModule2/src/main/kotlin", "myModule3/src/main/kotlin")
val mainPom = createProjectPom(""" val mainPom = createProjectPom(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1657,7 +1723,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
val modulePom1 = createModulePom( val modulePom1 = createModulePom(
"myModule1", "myModule1",
@@ -1857,9 +1924,15 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
} }
fun testMultiModuleImport() { fun testMultiModuleImport() {
createProjectSubDirs("src/main/kotlin", "my-common-module/src/main/kotlin", "my-jvm-module/src/main/kotlin", "my-js-module/src/main/kotlin") createProjectSubDirs(
"src/main/kotlin",
"my-common-module/src/main/kotlin",
"my-jvm-module/src/main/kotlin",
"my-js-module/src/main/kotlin"
)
val mainPom = createProjectPom(""" val mainPom = createProjectPom(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -1882,7 +1955,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
val commonModule = createModulePom( val commonModule = createModulePom(
"my-common-module", "my-common-module",
@@ -2054,7 +2128,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
try { try {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -2090,7 +2165,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -2099,8 +2175,7 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
Assert.assertTrue(moduleSDK.sdkType is JavaSdk) Assert.assertTrue(moduleSDK.sdkType is JavaSdk)
Assert.assertEquals("myJDK", moduleSDK.name) Assert.assertEquals("myJDK", moduleSDK.name)
Assert.assertEquals("my/path/to/jdk", moduleSDK.homePath) Assert.assertEquals("my/path/to/jdk", moduleSDK.homePath)
} } finally {
finally {
object : WriteAction<Unit>() { object : WriteAction<Unit>() {
override fun run(result: Result<Unit>) { override fun run(result: Result<Unit>) {
val jdkTable = ProjectJdkTable.getInstance() val jdkTable = ProjectJdkTable.getInstance()
@@ -2324,7 +2399,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
fun testNoArgDuplication() { fun testNoArgDuplication() {
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm") createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
importProject(""" importProject(
"""
<groupId>test</groupId> <groupId>test</groupId>
<artifactId>project</artifactId> <artifactId>project</artifactId>
<version>1.0.0</version> <version>1.0.0</version>
@@ -2362,7 +2438,8 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
</plugin> </plugin>
</plugins> </plugins>
</build> </build>
""") """
)
assertModules("project") assertModules("project")
assertImporterStatePresent() assertImporterStatePresent()
@@ -217,14 +217,17 @@ public abstract class MavenImportingTestCase extends MavenTestCase {
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPath == null ? null : Collections.singletonList(classesPath)); assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPath == null ? null : Collections.singletonList(classesPath));
assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePath == null ? null : Collections.singletonList(sourcePath)); assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePath == null ? null : Collections.singletonList(sourcePath));
assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(), javadocPath == null ? null : Collections.singletonList(javadocPath)); assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(),
javadocPath == null ? null : Collections.singletonList(javadocPath));
} }
protected void assertModuleLibDep(String moduleName, protected void assertModuleLibDep(
String moduleName,
String depName, String depName,
List<String> classesPaths, List<String> classesPaths,
List<String> sourcePaths, List<String> sourcePaths,
List<String> javadocPaths) { List<String> javadocPaths
) {
LibraryOrderEntry lib = getModuleLibDep(moduleName, depName); LibraryOrderEntry lib = getModuleLibDep(moduleName, depName);
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPaths); assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPaths);
@@ -255,7 +258,8 @@ public abstract class MavenImportingTestCase extends MavenTestCase {
protected void assertExportedDeps(String moduleName, String... expectedDeps) { protected void assertExportedDeps(String moduleName, String... expectedDeps) {
final List<String> actual = new ArrayList<String>(); final List<String> actual = new ArrayList<String>();
getRootManager(moduleName).orderEntries().withoutSdk().withoutModuleSourceEntries().exportedOnly().process(new RootPolicy<Object>() { getRootManager(moduleName).orderEntries().withoutSdk().withoutModuleSourceEntries().exportedOnly()
.process(new RootPolicy<Object>() {
@Override @Override
public Object visitModuleOrderEntry(ModuleOrderEntry e, Object value) { public Object visitModuleOrderEntry(ModuleOrderEntry e, Object value) {
actual.add(e.getModuleName()); actual.add(e.getModuleName());
@@ -507,8 +511,10 @@ public abstract class MavenImportingTestCase extends MavenTestCase {
downloadArtifacts(myProjectsManager.getProjects(), null); downloadArtifacts(myProjectsManager.getProjects(), null);
} }
protected MavenArtifactDownloader.DownloadResult downloadArtifacts(Collection<MavenProject> projects, protected MavenArtifactDownloader.DownloadResult downloadArtifacts(
List<MavenArtifact> artifacts) { Collection<MavenProject> projects,
List<MavenArtifact> artifacts
) {
final MavenArtifactDownloader.DownloadResult[] unresolved = new MavenArtifactDownloader.DownloadResult[1]; final MavenArtifactDownloader.DownloadResult[] unresolved = new MavenArtifactDownloader.DownloadResult[1];
AsyncResult<MavenArtifactDownloader.DownloadResult> result = new AsyncResult<MavenArtifactDownloader.DownloadResult>(); AsyncResult<MavenArtifactDownloader.DownloadResult> result = new AsyncResult<MavenArtifactDownloader.DownloadResult>();
@@ -137,7 +137,6 @@ public abstract class MavenTestCase extends UsefulTestCase {
}); });
} }
}); });
} }
private void ensureTempDirCreated() throws IOException { private void ensureTempDirCreated() throws IOException {
@@ -277,7 +276,9 @@ public abstract class MavenTestCase extends UsefulTestCase {
} }
protected static String getEnvVar() { protected static String getEnvVar() {
if (SystemInfo.isWindows) return "TEMP"; if (SystemInfo.isWindows) {
return "TEMP";
}
else if (SystemInfo.isLinux) return "HOME"; else if (SystemInfo.isLinux) return "HOME";
return "TMPDIR"; return "TMPDIR";
} }
@@ -409,7 +410,8 @@ public abstract class MavenTestCase extends UsefulTestCase {
return f; return f;
} }
@NonNls @Language(value="XML") @NonNls
@Language(value = "XML")
public static String createPomXml(@NonNls @Language(value = "XML", prefix = "<xml>", suffix = "</xml>") String xml) { public static String createPomXml(@NonNls @Language(value = "XML", prefix = "<xml>", suffix = "</xml>") String xml) {
return "<?xml version=\"1.0\"?>" + return "<?xml version=\"1.0\"?>" +
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\"" + "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"" +
@@ -542,6 +544,7 @@ public abstract class MavenTestCase extends UsefulTestCase {
protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, Collection<T> expected) { protected static <T> void assertUnorderedElementsAreEqual(Collection<T> actual, Collection<T> expected) {
assertEquals(new HashSet<T>(expected), new HashSet<T>(actual)); assertEquals(new HashSet<T>(expected), new HashSet<T>(actual));
} }
protected static void assertUnorderedPathsAreEqual(Collection<String> actual, Collection<String> expected) { protected static void assertUnorderedPathsAreEqual(Collection<String> actual, Collection<String> expected) {
assertEquals(new SetWithToString<String>(new THashSet<String>(expected, FileUtil.PATH_HASHING_STRATEGY)), assertEquals(new SetWithToString<String>(new THashSet<String>(expected, FileUtil.PATH_HASHING_STRATEGY)),
new SetWithToString<String>(new THashSet<String>(actual, FileUtil.PATH_HASHING_STRATEGY))); new SetWithToString<String>(new THashSet<String>(actual, FileUtil.PATH_HASHING_STRATEGY)));
@@ -641,5 +644,4 @@ public abstract class MavenTestCase extends UsefulTestCase {
return myDelegate.hashCode(); return myDelegate.hashCode();
} }
} }
} }
@@ -33,7 +33,8 @@ import kotlin.reflect.KMutableProperty0
class MavenUpdateConfigurationQuickFixTest : MavenImportingTestCase() { class MavenUpdateConfigurationQuickFixTest : MavenImportingTestCase() {
private lateinit var codeInsightTestFixture: CodeInsightTestFixture private lateinit var codeInsightTestFixture: CodeInsightTestFixture
fun getTestDataPath() = KotlinTestUtils.getHomeDirectory() + "/idea/idea-maven/testData/languageFeature/" + getTestName(true).substringBefore('_') private fun getTestDataPath() =
KotlinTestUtils.getHomeDirectory() + "/idea/idea-maven/testData/languageFeature/" + getTestName(true).substringBefore('_')
override fun setUpFixtures() { override fun setUpFixtures() {
myTestFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()).fixture myTestFixture = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()).fixture
@@ -43,31 +44,38 @@ class MavenUpdateConfigurationQuickFixTest : MavenImportingTestCase() {
override fun tearDownFixtures() { override fun tearDownFixtures() {
codeInsightTestFixture.tearDown() codeInsightTestFixture.tearDown()
@Suppress("UNCHECKED_CAST")
(this::codeInsightTestFixture as KMutableProperty0<CodeInsightTestFixture?>).set(null) (this::codeInsightTestFixture as KMutableProperty0<CodeInsightTestFixture?>).set(null)
myTestFixture = null myTestFixture = null
} }
@Test fun testUpdateLanguageVersion() { @Test
fun testUpdateLanguageVersion() {
doTest("Set module language version to 1.1") doTest("Set module language version to 1.1")
} }
@Test fun testUpdateLanguageVersionProperty() { @Test
fun testUpdateLanguageVersionProperty() {
doTest("Set module language version to 1.1") doTest("Set module language version to 1.1")
} }
@Test fun testUpdateApiVersion() { @Test
fun testUpdateApiVersion() {
doTest("Set module API version to 1.1") doTest("Set module API version to 1.1")
} }
@Test fun testUpdateLanguageAndApiVersion() { @Test
fun testUpdateLanguageAndApiVersion() {
doTest("Set module language version to 1.1") doTest("Set module language version to 1.1")
} }
@Test fun testEnableCoroutines() { @Test
fun testEnableCoroutines() {
doTest("Enable coroutine support in the current module") doTest("Enable coroutine support in the current module")
} }
@Test fun testAddKotlinReflect() { @Test
fun testAddKotlinReflect() {
doTest("Add kotlin-reflect.jar to the classpath") doTest("Add kotlin-reflect.jar to the classpath")
} }
@@ -39,7 +39,13 @@ abstract class AbstractMavenConfigureProjectByChangingFileTest : AbstractConfigu
doTest(pathWithFile, pathWithFile.replace("pom", "pom_after"), KotlinJavascriptMavenConfigurator()) doTest(pathWithFile, pathWithFile.replace("pom", "pom_after"), KotlinJavascriptMavenConfigurator())
} }
override fun runConfigurator(module: Module, file: PsiFile, configurator: KotlinMavenConfigurator, version: String, collector: NotificationMessageCollector) { override fun runConfigurator(
module: Module,
file: PsiFile,
configurator: KotlinMavenConfigurator,
version: String,
collector: NotificationMessageCollector
) {
WriteCommandAction.runWriteCommandAction(module.project) { WriteCommandAction.runWriteCommandAction(module.project) {
configurator.configureModule(module, file, version, collector) configurator.configureModule(module, file, version, collector)
} }