[lombok] Basic config support
This commit is contained in:
committed by
TeamCityServer
parent
5ceefa3e3b
commit
70e3877efc
+1
@@ -0,0 +1 @@
|
|||||||
|
org.jetbrains.kotlin.lombok.LombokCommandLineProcessor
|
||||||
-25
@@ -1,25 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
||||||
|
|
||||||
import com.intellij.mock.MockProject
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.extensions.SyntheticJavaResolveExtension
|
|
||||||
|
|
||||||
class LombokComponentRegistrar : ComponentRegistrar {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun registerComponents(project: Project) {
|
|
||||||
SyntheticJavaResolveExtension.registerExtension(project, LombokResolveExtension())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
|
|
||||||
registerComponents(project)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
||||||
|
|
||||||
|
import com.intellij.mock.MockProject
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption
|
||||||
|
import org.jetbrains.kotlin.compiler.plugin.CliOption
|
||||||
|
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
|
||||||
|
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||||
|
import org.jetbrains.kotlin.lombok.LombokConfigurationKeys.CONFIG_FILE
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.extensions.SyntheticJavaResolveExtension
|
||||||
|
import java.io.File
|
||||||
|
import java.lang.IllegalArgumentException
|
||||||
|
|
||||||
|
class LombokComponentRegistrar : ComponentRegistrar {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun registerComponents(project: Project, compilerConfiguration: CompilerConfiguration) {
|
||||||
|
val config = LombokPluginConfig(compilerConfiguration[CONFIG_FILE])
|
||||||
|
SyntheticJavaResolveExtension.registerExtension(project, LombokResolveExtension(config))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
|
||||||
|
registerComponents(project, configuration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data class LombokPluginConfig(val configFile: File?)
|
||||||
|
|
||||||
|
object LombokConfigurationKeys {
|
||||||
|
val CONFIG_FILE: CompilerConfigurationKey<File> = CompilerConfigurationKey.create("lombok config file location")
|
||||||
|
}
|
||||||
|
|
||||||
|
class LombokCommandLineProcessor : CommandLineProcessor {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val PLUGIN_ID = "org.jetbrains.kotlin.lombok"
|
||||||
|
|
||||||
|
val CONFIG_FILE_OPTION = CliOption(
|
||||||
|
optionName = "config",
|
||||||
|
valueDescription = "<path>",
|
||||||
|
description = "Lombok configuration file location",
|
||||||
|
required = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val pluginId: String = PLUGIN_ID
|
||||||
|
override val pluginOptions: Collection<AbstractCliOption> = listOf(CONFIG_FILE_OPTION)
|
||||||
|
|
||||||
|
override fun processOption(option: AbstractCliOption, value: String, configuration: CompilerConfiguration) {
|
||||||
|
when (option) {
|
||||||
|
CONFIG_FILE_OPTION -> configuration.put(CONFIG_FILE, File(value))
|
||||||
|
else -> throw IllegalArgumentException("Unknown option $option")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-2
@@ -5,10 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.lombok
|
package org.jetbrains.kotlin.lombok
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.lombok.config.LombokConfig
|
||||||
import org.jetbrains.kotlin.resolve.jvm.SyntheticJavaPartsProvider
|
import org.jetbrains.kotlin.resolve.jvm.SyntheticJavaPartsProvider
|
||||||
import org.jetbrains.kotlin.resolve.jvm.extensions.SyntheticJavaResolveExtension
|
import org.jetbrains.kotlin.resolve.jvm.extensions.SyntheticJavaResolveExtension
|
||||||
|
|
||||||
class LombokResolveExtension : SyntheticJavaResolveExtension {
|
class LombokResolveExtension(pluginConfig: LombokPluginConfig) : SyntheticJavaResolveExtension {
|
||||||
|
|
||||||
override fun getProvider(): SyntheticJavaPartsProvider = LombokSyntheticJavaPartsProvider()
|
private val config = pluginConfig.configFile?.let(LombokConfig::parse) ?: LombokConfig.Empty
|
||||||
|
|
||||||
|
override fun getProvider(): SyntheticJavaPartsProvider = LombokSyntheticJavaPartsProvider(config)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||||
|
import org.jetbrains.kotlin.lombok.config.LombokConfig
|
||||||
import org.jetbrains.kotlin.lombok.processor.GetterProcessor
|
import org.jetbrains.kotlin.lombok.processor.GetterProcessor
|
||||||
import org.jetbrains.kotlin.lombok.processor.Parts
|
import org.jetbrains.kotlin.lombok.processor.Parts
|
||||||
import org.jetbrains.kotlin.lombok.processor.Processor
|
import org.jetbrains.kotlin.lombok.processor.Processor
|
||||||
@@ -16,13 +17,13 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.SyntheticJavaPartsProvider
|
import org.jetbrains.kotlin.resolve.jvm.SyntheticJavaPartsProvider
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class LombokSyntheticJavaPartsProvider : SyntheticJavaPartsProvider {
|
class LombokSyntheticJavaPartsProvider(private val config: LombokConfig) : SyntheticJavaPartsProvider {
|
||||||
|
|
||||||
private val processors = initProcessors()
|
private val processors = initProcessors()
|
||||||
|
|
||||||
private fun initProcessors(): List<Processor> =
|
private fun initProcessors(): List<Processor> =
|
||||||
listOf(
|
listOf(
|
||||||
GetterProcessor()
|
GetterProcessor(config)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val partsCache: MutableMap<ClassDescriptor, Parts> = WeakHashMap()
|
private val partsCache: MutableMap<ClassDescriptor, Parts> = WeakHashMap()
|
||||||
|
|||||||
+28
-1
@@ -5,5 +5,32 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.lombok.config
|
package org.jetbrains.kotlin.lombok.config
|
||||||
|
|
||||||
class LombokConfig {
|
import java.io.File
|
||||||
|
|
||||||
|
class LombokConfig(private val config: Map<String, String>) {
|
||||||
|
|
||||||
|
fun getString(key: String): String? = config[key]
|
||||||
|
|
||||||
|
fun getBoolean(key: String): Boolean? = getString(key)?.toBoolean()
|
||||||
|
|
||||||
|
fun getBooleanOrDefault(key: String, default: Boolean = false): Boolean = getBoolean(key) ?: default
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
val Empty = LombokConfig(emptyMap())
|
||||||
|
|
||||||
|
fun parse(path: File): LombokConfig {
|
||||||
|
|
||||||
|
val config = mutableMapOf<String, String>()
|
||||||
|
|
||||||
|
path.forEachLine { line ->
|
||||||
|
val parts = line.split("=", limit = 2)
|
||||||
|
if (parts.size == 2) {
|
||||||
|
config[parts[0].trim()] = parts[1].trim()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LombokConfig(config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
|||||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||||
import org.jetbrains.kotlin.lombok.config.Accessors
|
import org.jetbrains.kotlin.lombok.config.Accessors
|
||||||
import org.jetbrains.kotlin.lombok.config.Getter
|
import org.jetbrains.kotlin.lombok.config.Getter
|
||||||
|
import org.jetbrains.kotlin.lombok.config.LombokConfig
|
||||||
import org.jetbrains.kotlin.lombok.utils.createFunction
|
import org.jetbrains.kotlin.lombok.utils.createFunction
|
||||||
import org.jetbrains.kotlin.lombok.utils.toPreparedBase
|
import org.jetbrains.kotlin.lombok.utils.toPreparedBase
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -19,7 +20,9 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isBoolean
|
import org.jetbrains.kotlin.types.typeUtil.isBoolean
|
||||||
|
|
||||||
class GetterProcessor : Processor {
|
class GetterProcessor(private val config: LombokConfig) : Processor {
|
||||||
|
|
||||||
|
private val noIsPrefix by lazy { config.getBooleanOrDefault("lombok.getter.noIsPrefix") }
|
||||||
|
|
||||||
override fun contribute(classDescriptor: ClassDescriptor, jClass: JavaClassImpl): Parts {
|
override fun contribute(classDescriptor: ClassDescriptor, jClass: JavaClassImpl): Parts {
|
||||||
val clAccessors = Accessors.getOrNull(classDescriptor)
|
val clAccessors = Accessors.getOrNull(classDescriptor)
|
||||||
@@ -46,7 +49,7 @@ class GetterProcessor : Processor {
|
|||||||
if (accessors.fluent) {
|
if (accessors.fluent) {
|
||||||
field.name.identifier
|
field.name.identifier
|
||||||
} else {
|
} else {
|
||||||
val prefix = if (field.type.isPrimitiveBoolean()) "is" else "get"
|
val prefix = if (field.type.isPrimitiveBoolean() && !noIsPrefix) "is" else "get"
|
||||||
prefix + toPreparedBase(field.name.identifier)
|
prefix + toPreparedBase(field.name.identifier)
|
||||||
}
|
}
|
||||||
return createFunction(
|
return createFunction(
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//FILE: GetterTest.java
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
public class GetterTest {
|
||||||
|
@Getter private boolean primitiveBoolean;
|
||||||
|
|
||||||
|
void test() {
|
||||||
|
getPrimitiveBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//FILE: test.kt
|
||||||
|
|
||||||
|
object Test {
|
||||||
|
fun usage() {
|
||||||
|
val obj = GetterTest()
|
||||||
|
|
||||||
|
obj.primitiveBoolean
|
||||||
|
obj.getPrimitiveBoolean()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//FILE: lombok.config
|
||||||
|
lombok.getter.noIsPrefix=true
|
||||||
@@ -8,6 +8,8 @@ import lombok.experimental.Accessors;
|
|||||||
public class FluentTest {
|
public class FluentTest {
|
||||||
@Getter private int age = 10;
|
@Getter private int age = 10;
|
||||||
|
|
||||||
|
@Getter @Accessors private int overrideAnnotation = 10;
|
||||||
|
|
||||||
@Getter(AccessLevel.PROTECTED) private String name;
|
@Getter(AccessLevel.PROTECTED) private String name;
|
||||||
|
|
||||||
@Getter private boolean primitiveBoolean;
|
@Getter private boolean primitiveBoolean;
|
||||||
@@ -17,6 +19,7 @@ public class FluentTest {
|
|||||||
void test() {
|
void test() {
|
||||||
age();
|
age();
|
||||||
primitiveBoolean();
|
primitiveBoolean();
|
||||||
|
getOverrideAnnotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -32,6 +35,9 @@ object Test {
|
|||||||
obj.primitiveBoolean()
|
obj.primitiveBoolean()
|
||||||
|
|
||||||
obj.boxedBoolean()
|
obj.boxedBoolean()
|
||||||
|
|
||||||
|
obj.overrideAnnotation
|
||||||
|
obj.getOverrideAnnotation()
|
||||||
}
|
}
|
||||||
|
|
||||||
class OverridenGetterTest : FluentTest() {
|
class OverridenGetterTest : FluentTest() {
|
||||||
|
|||||||
+17
-1
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.lombok
|
|||||||
import lombok.Getter
|
import lombok.Getter
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.config.javaSourceRoots
|
||||||
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
import org.jetbrains.kotlin.codegen.CodegenTestCase
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.utils.PathUtil
|
import org.jetbrains.kotlin.utils.PathUtil
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -19,7 +21,7 @@ abstract class AbstractLombokCompileTest : CodegenTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun setupEnvironment(environment: KotlinCoreEnvironment) {
|
override fun setupEnvironment(environment: KotlinCoreEnvironment) {
|
||||||
LombokComponentRegistrar.registerComponents(environment.project)
|
LombokComponentRegistrar.registerComponents(environment.project, environment.configuration)
|
||||||
environment.updateClasspath(listOf(JvmClasspathRoot(getLombokJar())))
|
environment.updateClasspath(listOf(JvmClasspathRoot(getLombokJar())))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,5 +29,19 @@ abstract class AbstractLombokCompileTest : CodegenTestCase() {
|
|||||||
javaClasspath += getLombokJar().absolutePath
|
javaClasspath += getLombokJar().absolutePath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun configureTestSpecific(configuration: CompilerConfiguration, testFiles: List<TestFile>) {
|
||||||
|
writeLombokConfig(configuration.javaSourceRoots.first(), testFiles)?.let { file ->
|
||||||
|
configuration.put(LombokConfigurationKeys.CONFIG_FILE, file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun writeLombokConfig(directory: String, testFiles: List<TestFile>): File? =
|
||||||
|
testFiles.singleOrNull { it.name == "lombok.config" }?.let {
|
||||||
|
val file = File(directory, it.name)
|
||||||
|
file.writeText(it.content)
|
||||||
|
file
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getLombokJar(): File = PathUtil.getResourcePathForClass(Getter::class.java)
|
private fun getLombokJar(): File = PathUtil.getResourcePathForClass(Getter::class.java)
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -15,7 +15,9 @@ import org.junit.runner.RunWith;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
/**
|
||||||
|
* This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY
|
||||||
|
*/
|
||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("plugins/lombok/lombok-compiler-plugin/testData/compile")
|
@TestMetadata("plugins/lombok/lombok-compiler-plugin/testData/compile")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@@ -29,6 +31,11 @@ public class LombokCompileTestGenerated extends AbstractLombokCompileTest {
|
|||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/lombok/lombok-compiler-plugin/testData/compile"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/lombok/lombok-compiler-plugin/testData/compile"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("configSimple.kt")
|
||||||
|
public void testConfigSimple() throws Exception {
|
||||||
|
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/configSimple.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("gettersClassLevel.kt")
|
@TestMetadata("gettersClassLevel.kt")
|
||||||
public void testGettersClassLevel() throws Exception {
|
public void testGettersClassLevel() throws Exception {
|
||||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/gettersClassLevel.kt");
|
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/gettersClassLevel.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user