[lombok] Use config values as default in annotation parsing
This commit is contained in:
committed by
TeamCityServer
parent
c7b2c731af
commit
8a2279de2b
@@ -13,7 +13,13 @@ Features support:
|
|||||||
- [x] Basic support
|
- [x] Basic support
|
||||||
- [x] Class-level
|
- [x] Class-level
|
||||||
- [x] @Accessors config support: chain and fluent
|
- [x] @Accessors config support: chain and fluent
|
||||||
- [ ] Config support (_lombok.getter.noIsPrefix_ only supported atm)
|
- [~] Config support
|
||||||
|
- [x] lombok.getter.noIsPrefix
|
||||||
|
- [x] lombok.accessors.fluent
|
||||||
|
- [x] lombok.accessors.chain
|
||||||
|
- [ ] lombok.accessors.prefix
|
||||||
|
- [ ] lombok.noArgsConstructor.extraPrivate
|
||||||
|
- [ ] lombok.copyableAnnotations
|
||||||
- [ ] Copy annotations
|
- [ ] Copy annotations
|
||||||
- [ ] Strip defined prefixes - in config and @Accessors
|
- [ ] Strip defined prefixes - in config and @Accessors
|
||||||
- [ ] Skip generation with AccessLevel.NONE
|
- [ ] Skip generation with AccessLevel.NONE
|
||||||
|
|||||||
+43
-10
@@ -15,6 +15,14 @@ import org.jetbrains.kotlin.lombok.utils.getNonBlankStringArgument
|
|||||||
import org.jetbrains.kotlin.lombok.utils.getVisibility
|
import org.jetbrains.kotlin.lombok.utils.getVisibility
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lombok has two ways of configuration - lombok.config file and directly in annotations. Annotations has priority.
|
||||||
|
* Not all things can be configured in annotations
|
||||||
|
* So to make things easier I put all configuration in 'annotations' classes, but populate them from config too. So far it allows
|
||||||
|
* keeping processors' code unaware about configuration origin.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
abstract class AnnotationCompanion<T> {
|
abstract class AnnotationCompanion<T> {
|
||||||
|
|
||||||
abstract val name: FqName
|
abstract val name: FqName
|
||||||
@@ -25,19 +33,44 @@ abstract class AnnotationCompanion<T> {
|
|||||||
annotated.annotations.findAnnotation(name)?.let(this::extract)
|
annotated.annotations.findAnnotation(name)?.let(this::extract)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class AnnotationAndConfigCompanion<T> {
|
||||||
|
|
||||||
|
abstract val annotationName: FqName
|
||||||
|
|
||||||
|
|
||||||
|
abstract fun extract(annotation: AnnotationDescriptor?, config: LombokConfig): T
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get from annotation or config or default
|
||||||
|
*/
|
||||||
|
fun get(annotated: Annotated, config: LombokConfig): T =
|
||||||
|
extract(annotated.annotations.findAnnotation(annotationName), config)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If element is annotated, get from it or config or default
|
||||||
|
*/
|
||||||
|
fun getIfAnnotated(annotated: Annotated, config: LombokConfig): T? =
|
||||||
|
annotated.annotations.findAnnotation(annotationName)?.let { annotation ->
|
||||||
|
extract(annotation, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
data class Accessors(val fluent: Boolean = false, val chain: Boolean = false) {
|
data class Accessors(val fluent: Boolean = false, val chain: Boolean = false) {
|
||||||
companion object : AnnotationCompanion<Accessors>() {
|
companion object : AnnotationAndConfigCompanion<Accessors>() {
|
||||||
|
|
||||||
val default = Accessors()
|
override val annotationName: FqName = LombokNames.ACCESSORS
|
||||||
|
|
||||||
override val name: FqName = LombokNames.ACCESSORS
|
override fun extract(annotation: AnnotationDescriptor?, config: LombokConfig): Accessors {
|
||||||
|
val fluent =
|
||||||
override fun extract(annotation: AnnotationDescriptor): Accessors {
|
annotation?.getBooleanArgument("fluent")
|
||||||
val fluent = annotation.getBooleanArgument("fluent")
|
?: config.getBoolean("lombok.accessors.fluent")
|
||||||
return Accessors(
|
?: false
|
||||||
fluent = fluent,
|
val chain =
|
||||||
chain = annotation.getBooleanArgument("chain", default = fluent)
|
annotation?.getBooleanArgument("chain")
|
||||||
)
|
?: config.getBoolean("lombok.accessors.chain")
|
||||||
|
?: fluent
|
||||||
|
return Accessors(fluent, chain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -24,7 +24,7 @@ class GetterProcessor(private val config: LombokConfig) : Processor {
|
|||||||
private val noIsPrefix by lazy { config.getBooleanOrDefault("lombok.getter.noIsPrefix") }
|
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 globalAccessors = Accessors.get(classDescriptor, config)
|
||||||
val clGetter =
|
val clGetter =
|
||||||
Getter.getOrNull(classDescriptor)
|
Getter.getOrNull(classDescriptor)
|
||||||
?: Data.getOrNull(classDescriptor)?.asGetter()
|
?: Data.getOrNull(classDescriptor)?.asGetter()
|
||||||
@@ -33,7 +33,7 @@ class GetterProcessor(private val config: LombokConfig) : Processor {
|
|||||||
val functions = classDescriptor
|
val functions = classDescriptor
|
||||||
.getJavaFields()
|
.getJavaFields()
|
||||||
.collectWithNotNull { Getter.getOrNull(it) ?: clGetter }
|
.collectWithNotNull { Getter.getOrNull(it) ?: clGetter }
|
||||||
.mapNotNull { (field, annotation) -> createGetter(classDescriptor, field, annotation, clAccessors) }
|
.mapNotNull { (field, annotation) -> createGetter(classDescriptor, field, annotation, globalAccessors) }
|
||||||
|
|
||||||
return Parts(functions)
|
return Parts(functions)
|
||||||
}
|
}
|
||||||
@@ -42,9 +42,9 @@ class GetterProcessor(private val config: LombokConfig) : Processor {
|
|||||||
classDescriptor: ClassDescriptor,
|
classDescriptor: ClassDescriptor,
|
||||||
field: PropertyDescriptor,
|
field: PropertyDescriptor,
|
||||||
getter: Getter,
|
getter: Getter,
|
||||||
classLevelAccessors: Accessors?
|
globalAccessors: Accessors
|
||||||
): SimpleFunctionDescriptor? {
|
): SimpleFunctionDescriptor? {
|
||||||
val accessors = Accessors.getOrNull(field) ?: classLevelAccessors ?: Accessors.default
|
val accessors = Accessors.getIfAnnotated(field, config) ?: globalAccessors
|
||||||
|
|
||||||
val functionName =
|
val functionName =
|
||||||
if (accessors.fluent) {
|
if (accessors.fluent) {
|
||||||
|
|||||||
+4
-4
@@ -21,13 +21,13 @@ class SetterProcessor(private val config: LombokConfig) : Processor {
|
|||||||
//lombok doesn't generate setters for enums
|
//lombok doesn't generate setters for enums
|
||||||
if (classDescriptor.kind == ClassKind.ENUM_CLASS) return Parts.Empty
|
if (classDescriptor.kind == ClassKind.ENUM_CLASS) return Parts.Empty
|
||||||
|
|
||||||
val clAccessors = Accessors.getOrNull(classDescriptor)
|
val globalAccessors = Accessors.get(classDescriptor, config)
|
||||||
val clSetter = Setter.getOrNull(classDescriptor) ?: Data.getOrNull(classDescriptor)?.asSetter()
|
val clSetter = Setter.getOrNull(classDescriptor) ?: Data.getOrNull(classDescriptor)?.asSetter()
|
||||||
|
|
||||||
val functions = classDescriptor
|
val functions = classDescriptor
|
||||||
.getJavaFields()
|
.getJavaFields()
|
||||||
.collectWithNotNull { field -> Setter.getOrNull(field) ?: clSetter.takeIf { field.isVar } }
|
.collectWithNotNull { field -> Setter.getOrNull(field) ?: clSetter.takeIf { field.isVar } }
|
||||||
.mapNotNull { (field, setter) -> createSetter(classDescriptor, field, setter, clAccessors) }
|
.mapNotNull { (field, setter) -> createSetter(classDescriptor, field, setter, globalAccessors) }
|
||||||
return Parts(functions)
|
return Parts(functions)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,9 +35,9 @@ class SetterProcessor(private val config: LombokConfig) : Processor {
|
|||||||
classDescriptor: ClassDescriptor,
|
classDescriptor: ClassDescriptor,
|
||||||
field: PropertyDescriptor,
|
field: PropertyDescriptor,
|
||||||
getter: Setter,
|
getter: Setter,
|
||||||
classLevelAccessors: Accessors?
|
globalAccessors: Accessors
|
||||||
): SimpleFunctionDescriptor? {
|
): SimpleFunctionDescriptor? {
|
||||||
val accessors = Accessors.getOrNull(field) ?: classLevelAccessors ?: Accessors.default
|
val accessors = Accessors.getIfAnnotated(field, config) ?: globalAccessors
|
||||||
|
|
||||||
val functionName =
|
val functionName =
|
||||||
if (accessors.fluent) {
|
if (accessors.fluent) {
|
||||||
|
|||||||
+2
-2
@@ -42,9 +42,9 @@ fun AnnotationDescriptor.getStringArgument(argumentName: String): String? {
|
|||||||
fun AnnotationDescriptor.getNonBlankStringArgument(argumentName: String): String? =
|
fun AnnotationDescriptor.getNonBlankStringArgument(argumentName: String): String? =
|
||||||
getStringArgument(argumentName).trimToNull()
|
getStringArgument(argumentName).trimToNull()
|
||||||
|
|
||||||
fun AnnotationDescriptor.getBooleanArgument(argumentName: String, default: Boolean = false): Boolean {
|
fun AnnotationDescriptor.getBooleanArgument(argumentName: String): Boolean? {
|
||||||
val argument = allValueArguments[Name.identifier(argumentName)]
|
val argument = allValueArguments[Name.identifier(argumentName)]
|
||||||
?: return default
|
?: return null
|
||||||
|
|
||||||
return when (argument) {
|
return when (argument) {
|
||||||
is BooleanValue -> argument.value
|
is BooleanValue -> argument.value
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
//FILE: GetterTest.java
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class GetterTest {
|
||||||
|
private String name;
|
||||||
|
private int age;
|
||||||
|
|
||||||
|
static void test() {
|
||||||
|
val obj = new GetterTest();
|
||||||
|
GetterTest ref = obj.name("some").age(34);
|
||||||
|
obj.name();
|
||||||
|
obj.age();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//FILE: test.kt
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
fun run() {
|
||||||
|
val obj = GetterTest()
|
||||||
|
val ref: GetterTest = obj.name("some").age(34)
|
||||||
|
obj.name()
|
||||||
|
obj.age()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//FILE: lombok.config
|
||||||
|
lombok.accessors.fluent=true
|
||||||
|
//lombok.accessors.chain=false
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
//FILE: GetterTest.java
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.*;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
public class GetterTest {
|
||||||
|
private String name;
|
||||||
|
private int age;
|
||||||
|
@Accessors(chain = true)
|
||||||
|
private boolean fluent;
|
||||||
|
|
||||||
|
static void test() {
|
||||||
|
val obj = new GetterTest();
|
||||||
|
GetterTest ref = obj.fluent(true);
|
||||||
|
obj.name();
|
||||||
|
obj.age();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//FILE: test.kt
|
||||||
|
|
||||||
|
class Test {
|
||||||
|
fun run() {
|
||||||
|
val obj = GetterTest()
|
||||||
|
val ref: GetterTest = obj.fluent(true)
|
||||||
|
obj.name()
|
||||||
|
obj.age()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//FILE: lombok.config
|
||||||
|
lombok.accessors.fluent=true
|
||||||
|
lombok.accessors.chain=false
|
||||||
+15
-5
@@ -31,11 +31,6 @@ 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("allArgsConstructor.kt")
|
@TestMetadata("allArgsConstructor.kt")
|
||||||
public void testAllArgsConstructor() throws Exception {
|
public void testAllArgsConstructor() throws Exception {
|
||||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/allArgsConstructor.kt");
|
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/allArgsConstructor.kt");
|
||||||
@@ -51,6 +46,21 @@ public class LombokCompileTestGenerated extends AbstractLombokCompileTest {
|
|||||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/clashAccessors.kt");
|
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/clashAccessors.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("configAccessors.kt")
|
||||||
|
public void testConfigAccessors() throws Exception {
|
||||||
|
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/configAccessors.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("configAccessorsOverride.kt")
|
||||||
|
public void testConfigAccessorsOverride() throws Exception {
|
||||||
|
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/configAccessorsOverride.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("configSimple.kt")
|
||||||
|
public void testConfigSimple() throws Exception {
|
||||||
|
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/configSimple.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("data.kt")
|
@TestMetadata("data.kt")
|
||||||
public void testData() throws Exception {
|
public void testData() throws Exception {
|
||||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/data.kt");
|
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/data.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user