[lombok] IDE plugin with maven import handler

This commit is contained in:
Andrey Zinovyev
2021-04-23 10:21:33 +03:00
committed by TeamCityServer
parent 07daf2165a
commit b58bea6fa1
12 changed files with 201 additions and 2 deletions
@@ -0,0 +1,34 @@
description = "Lombok IDE plugin"
plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
implementation(project(":plugins:lombok:lombok-compiler-plugin"))
compileOnly(project(":idea"))
compileOnly(project(":idea:idea-jvm"))
compileOnly(project(":idea:idea-jps-common"))
compileOnly(project(":idea:idea-maven"))
compileOnly(intellijDep())
excludeInAndroidStudio(rootProject) { compileOnly(intellijPluginDep("maven")) }
compileOnly(intellijPluginDep("gradle"))
compileOnly(project(":idea:kotlin-gradle-tooling"))
}
sourceSets {
"main" { projectDefault() }
"test" { projectDefault() }
}
runtimeJar()
sourcesJar()
javadocJar()
projectTest(parallel = true)
apply(from = "$rootDir/gradle/kotlinPluginPublication.gradle.kts")
@@ -0,0 +1,63 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.lombok.ide
import org.jdom.Element
import org.jdom.Text
import org.jetbrains.idea.maven.project.MavenProject
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.maven.MavenProjectImportHandler
import org.jetbrains.kotlin.idea.maven.KotlinMavenImporter.Companion.KOTLIN_PLUGIN_GROUP_ID
import org.jetbrains.kotlin.idea.maven.KotlinMavenImporter.Companion.KOTLIN_PLUGIN_ARTIFACT_ID
import java.io.File
import org.jetbrains.kotlin.lombok.ide.CompilerPluginSetup.PluginOption
abstract class AbstractMavenImportHandler : MavenProjectImportHandler {
abstract val compilerPluginId: String
abstract val pluginName: String
// abstract val mavenPluginArtifactName: String
abstract val pluginJarFileFromIdea: File
override fun invoke(facet: KotlinFacet, mavenProject: MavenProject) {
modifyCompilerArgumentsForPlugin(
facet, getPluginSetup(mavenProject),
compilerPluginId = compilerPluginId,
pluginName = pluginName
)
}
abstract fun getOptions(enabledCompilerPlugins: List<String>, compilerPluginOptions: List<String>): List<PluginOption>?
private fun getPluginSetup(mavenProject: MavenProject): CompilerPluginSetup? {
val kotlinPlugin = mavenProject.plugins.firstOrNull {
it.groupId == KOTLIN_PLUGIN_GROUP_ID && it.artifactId == KOTLIN_PLUGIN_ARTIFACT_ID
} ?: return null
val configuration = kotlinPlugin.configurationElement ?: return null
val enabledCompilerPlugins = configuration.getElement("compilerPlugins")
?.getElements()
?.flatMap { plugin -> plugin.content.mapNotNull { (it as? Text)?.text } }
?: emptyList()
val compilerPluginOptions = configuration.getElement("pluginOptions")
?.getElements()
?.flatMap { it.content }
?.mapTo(mutableListOf()) { (it as Text).text }
?: mutableListOf<String>()
// We can't use the plugin from Gradle as it may have the incompatible version
val classpath = listOf(pluginJarFileFromIdea.absolutePath)
val options = getOptions(enabledCompilerPlugins, compilerPluginOptions) ?: return null
return CompilerPluginSetup(options, classpath)
}
private fun Element.getElement(name: String) = content.firstOrNull { it is Element && it.name == name } as? Element
@Suppress("UNCHECKED_CAST")
private fun Element.getElements() = content.filterIsInstance<Element>()
}
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.lombok.ide
import org.jetbrains.kotlin.lombok.LombokCommandLineProcessor
import org.jetbrains.kotlin.lombok.LombokCommandLineProcessor.Companion.CONFIG_FILE_OPTION
import org.jetbrains.kotlin.lombok.ide.CompilerPluginSetup.PluginOption
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
class LombokMavenProjectImportHandler : AbstractMavenImportHandler() {
override val compilerPluginId: String = LombokCommandLineProcessor.PLUGIN_ID
override val pluginName: String = MAVEN_SUBPLUGIN_NAME
override val pluginJarFileFromIdea: File = PathUtil.kotlinPathsForIdeaPlugin.lombokPluginJarPath
override fun getOptions(
enabledCompilerPlugins: List<String>,
compilerPluginOptions: List<String>
): List<PluginOption>? {
if (!enabledCompilerPlugins.contains(pluginName)) return null
return compilerPluginOptions.mapNotNull { v ->
if (v.startsWith(CONFIG_FILE_PREFIX)) {
val location = v.substring(CONFIG_FILE_PREFIX.length)
PluginOption(CONFIG_FILE_OPTION.optionName, location)
} else {
null
}
}
}
companion object {
private const val MAVEN_SUBPLUGIN_NAME = "lombok"
private val CONFIG_FILE_PREFIX = "$MAVEN_SUBPLUGIN_NAME:${CONFIG_FILE_OPTION.optionName}="
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.lombok.ide
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import java.io.File
class CompilerPluginSetup(val options: List<PluginOption>, val classpath: List<String>) {
class PluginOption(val key: String, val value: String)
}
internal fun modifyCompilerArgumentsForPlugin(
facet: KotlinFacet,
setup: CompilerPluginSetup?,
compilerPluginId: String,
pluginName: String
) {
val facetSettings = facet.configuration.settings
// investigate why copyBean() sometimes throws exceptions
val commonArguments = facetSettings.compilerArguments ?: CommonCompilerArguments.DummyImpl()
/** See [CommonCompilerArguments.PLUGIN_OPTION_FORMAT] **/
val newOptionsForPlugin = setup?.options?.map { "plugin:$compilerPluginId:${it.key}=${it.value}" } ?: emptyList()
val oldAllPluginOptions =
(commonArguments.pluginOptions ?: emptyArray()).filterTo(mutableListOf()) { !it.startsWith("plugin:$compilerPluginId:") }
val newAllPluginOptions = oldAllPluginOptions + newOptionsForPlugin
val oldPluginClasspaths = (commonArguments.pluginClasspaths ?: emptyArray()).filterTo(mutableListOf()) {
val lastIndexOfFile = it.lastIndexOfAny(charArrayOf('/', File.separatorChar))
if (lastIndexOfFile < 0) {
return@filterTo true
}
!it.drop(lastIndexOfFile + 1).matches("(kotlin-)?(maven-)?$pluginName-.*\\.jar".toRegex())
}
val newPluginClasspaths = oldPluginClasspaths + (setup?.classpath ?: emptyList())
commonArguments.pluginOptions = newAllPluginOptions.toTypedArray()
commonArguments.pluginClasspaths = newPluginClasspaths.toTypedArray()
facetSettings.compilerArguments = commonArguments
}