[lombok] Strip 'is' prefix in boolean properties
This commit is contained in:
committed by
TeamCityServer
parent
8a2279de2b
commit
f2c0b8c68d
@@ -23,7 +23,7 @@ Features support:
|
||||
- [ ] Copy annotations
|
||||
- [ ] Strip defined prefixes - in config and @Accessors
|
||||
- [ ] Skip generation with AccessLevel.NONE
|
||||
- [ ] Strip 'is' prefix for boolean fields
|
||||
- [x] Strip 'is' prefix for boolean fields
|
||||
|
||||
[~] [@With](https://projectlombok.org/features/With)
|
||||
|
||||
|
||||
+12
-6
@@ -9,10 +9,7 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.lombok.utils.LombokNames
|
||||
import org.jetbrains.kotlin.lombok.utils.getBooleanArgument
|
||||
import org.jetbrains.kotlin.lombok.utils.getNonBlankStringArgument
|
||||
import org.jetbrains.kotlin.lombok.utils.getVisibility
|
||||
import org.jetbrains.kotlin.lombok.utils.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
/*
|
||||
@@ -56,7 +53,12 @@ abstract class AnnotationAndConfigCompanion<T> {
|
||||
|
||||
}
|
||||
|
||||
data class Accessors(val fluent: Boolean = false, val chain: Boolean = false) {
|
||||
data class Accessors(
|
||||
val fluent: Boolean = false,
|
||||
val chain: Boolean = false,
|
||||
val noIsPrefix: Boolean = false,
|
||||
val prefix: List<String> = emptyList()
|
||||
) {
|
||||
companion object : AnnotationAndConfigCompanion<Accessors>() {
|
||||
|
||||
override val annotationName: FqName = LombokNames.ACCESSORS
|
||||
@@ -70,7 +72,11 @@ data class Accessors(val fluent: Boolean = false, val chain: Boolean = false) {
|
||||
annotation?.getBooleanArgument("chain")
|
||||
?: config.getBoolean("lombok.accessors.chain")
|
||||
?: fluent
|
||||
return Accessors(fluent, chain)
|
||||
val noIsPrefix = config.getBoolean("lombok.getter.noIsPrefix") ?: false
|
||||
val prefix = annotation?.getStringArrayArgument("prefix")
|
||||
?: emptyList()
|
||||
|
||||
return Accessors(fluent, chain, noIsPrefix, prefix)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-15
@@ -10,19 +10,11 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||
import org.jetbrains.kotlin.lombok.config.*
|
||||
import org.jetbrains.kotlin.lombok.utils.collectWithNotNull
|
||||
import org.jetbrains.kotlin.lombok.utils.createFunction
|
||||
import org.jetbrains.kotlin.lombok.utils.getJavaFields
|
||||
import org.jetbrains.kotlin.lombok.utils.toPreparedBase
|
||||
import org.jetbrains.kotlin.lombok.utils.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
import org.jetbrains.kotlin.types.typeUtil.isBoolean
|
||||
|
||||
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 {
|
||||
val globalAccessors = Accessors.get(classDescriptor, config)
|
||||
val clGetter =
|
||||
@@ -45,13 +37,13 @@ class GetterProcessor(private val config: LombokConfig) : Processor {
|
||||
globalAccessors: Accessors
|
||||
): SimpleFunctionDescriptor? {
|
||||
val accessors = Accessors.getIfAnnotated(field, config) ?: globalAccessors
|
||||
|
||||
val propertyName = field.toPropertyName(accessors)
|
||||
val functionName =
|
||||
if (accessors.fluent) {
|
||||
field.name.identifier
|
||||
propertyName
|
||||
} else {
|
||||
val prefix = if (field.type.isPrimitiveBoolean() && !noIsPrefix) "is" else "get"
|
||||
prefix + toPreparedBase(field.name.identifier)
|
||||
val prefix = if (field.type.isPrimitiveBoolean() && !accessors.noIsPrefix) AccessorNames.IS else AccessorNames.GET
|
||||
prefix + propertyName.capitalize()
|
||||
}
|
||||
return classDescriptor.createFunction(
|
||||
Name.identifier(functionName),
|
||||
@@ -61,6 +53,4 @@ class GetterProcessor(private val config: LombokConfig) : Processor {
|
||||
)
|
||||
}
|
||||
|
||||
private fun KotlinType.isPrimitiveBoolean(): Boolean = this is SimpleTypeMarker && isBoolean() //todo
|
||||
|
||||
}
|
||||
|
||||
+3
-5
@@ -38,13 +38,11 @@ class SetterProcessor(private val config: LombokConfig) : Processor {
|
||||
globalAccessors: Accessors
|
||||
): SimpleFunctionDescriptor? {
|
||||
val accessors = Accessors.getIfAnnotated(field, config) ?: globalAccessors
|
||||
val propertyName = field.toPropertyName(accessors)
|
||||
|
||||
val functionName =
|
||||
if (accessors.fluent) {
|
||||
field.name.identifier
|
||||
} else {
|
||||
"set" + toPreparedBase(field.name.identifier)
|
||||
}
|
||||
if (accessors.fluent) propertyName
|
||||
else AccessorNames.SET + propertyName.capitalize()
|
||||
|
||||
val returnType = if (accessors.chain) classDescriptor.defaultType else classDescriptor.builtIns.unitType
|
||||
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class WithProcessor(private val config: LombokConfig) : Processor {
|
||||
with: With
|
||||
): SimpleFunctionDescriptor? {
|
||||
|
||||
val functionName = "with" + toPreparedBase(field.name.identifier)
|
||||
val functionName = "with" + toPropertyNameCapitalized(field.name.identifier)
|
||||
|
||||
return classDescriptor.createFunction(
|
||||
Name.identifier(functionName),
|
||||
|
||||
+14
-8
@@ -12,9 +12,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.java.JavaVisibilities
|
||||
import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.constants.BooleanValue
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.constants.*
|
||||
|
||||
fun getVisibility(annotation: AnnotationDescriptor, field: String = "value"): DescriptorVisibility {
|
||||
val value = annotation.getStringArgument(field) ?: "PUBLIC"
|
||||
@@ -32,11 +30,19 @@ fun AnnotationDescriptor.getStringArgument(argumentName: String): String? {
|
||||
val argument = allValueArguments[Name.identifier(argumentName)]
|
||||
?: return null
|
||||
|
||||
return when (argument) {
|
||||
is EnumValue -> argument.enumEntryName.identifier
|
||||
is StringValue -> argument.value
|
||||
else -> throw RuntimeException("Argument $argument is not supported")
|
||||
}
|
||||
return extractString(argument)
|
||||
}
|
||||
|
||||
fun AnnotationDescriptor.getStringArrayArgument(argumentName: String): List<String>? {
|
||||
val argument = allValueArguments[Name.identifier(argumentName)] ?: return emptyList()
|
||||
if (argument !is ArrayValue) throw RuntimeException("Argument should be ArrayValue, got $argument")
|
||||
return argument.value.map(::extractString)
|
||||
}
|
||||
|
||||
private fun extractString(argument: ConstantValue<*>) = when (argument) {
|
||||
is EnumValue -> argument.enumEntryName.identifier
|
||||
is StringValue -> argument.value
|
||||
else -> throw RuntimeException("Argument $argument is not supported")
|
||||
}
|
||||
|
||||
fun AnnotationDescriptor.getNonBlankStringArgument(argumentName: String): String? =
|
||||
|
||||
+4
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
import org.jetbrains.kotlin.types.typeUtil.isBoolean
|
||||
|
||||
data class ValueParameter(val name: Name, val type: KotlinType)
|
||||
|
||||
@@ -93,3 +95,5 @@ fun ClassDescriptor.getJavaFields(): List<PropertyDescriptor> =
|
||||
.map {
|
||||
this.unsubstitutedMemberScope.getContributedVariables(it, NoLookupLocation.FROM_SYNTHETIC_SCOPE).single()
|
||||
}.filter { it.isJavaField }
|
||||
|
||||
fun KotlinType.isPrimitiveBoolean(): Boolean = this is SimpleTypeMarker && isBoolean()
|
||||
|
||||
+28
-2
@@ -5,6 +5,32 @@
|
||||
|
||||
package org.jetbrains.kotlin.lombok.utils
|
||||
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.lombok.config.Accessors
|
||||
|
||||
fun toPreparedBase(name: String): String = name.capitalizeAsciiOnly()
|
||||
object AccessorNames {
|
||||
const val IS = "is"
|
||||
const val GET = "get"
|
||||
const val SET = "set"
|
||||
}
|
||||
|
||||
fun PropertyDescriptor.toPropertyName(config: Accessors): String {
|
||||
val isPrimitiveBoolean = type.isPrimitiveBoolean()
|
||||
val prefixes = if (isPrimitiveBoolean) config.prefix + AccessorNames.IS else config.prefix
|
||||
return toPropertyName(name.identifier, prefixes)
|
||||
}
|
||||
|
||||
fun toPropertyName(name: String, prefixesToStrip: List<String> = emptyList()): String =
|
||||
name.stripPrefixes(prefixesToStrip)
|
||||
|
||||
fun toPropertyNameCapitalized(name: String, prefixesToStrip: List<String> = emptyList()): String =
|
||||
name.stripPrefixes(prefixesToStrip).capitalize()
|
||||
|
||||
private fun String.stripPrefixes(prefixes: List<String>): String =
|
||||
prefixes.firstOrNull { isPrefix(it) }?.let { prefix ->
|
||||
drop(prefix.length)
|
||||
} ?: this
|
||||
|
||||
|
||||
private fun String.isPrefix(prefix: String): Boolean =
|
||||
length > prefix.length && startsWith(prefix) && get(prefix.length).isUpperCase()
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
//FILE: AccessorsTest.java
|
||||
|
||||
import lombok.*;
|
||||
import lombok.experimental.*;
|
||||
|
||||
@Getter @Setter
|
||||
public class AccessorsTest {
|
||||
private int age = 10;
|
||||
|
||||
private boolean isHuman;
|
||||
private Boolean isNonPrimitiveHuman;
|
||||
|
||||
static void test() {
|
||||
val obj = new AccessorsTest();
|
||||
|
||||
obj.getAge();
|
||||
|
||||
obj.isHuman();
|
||||
obj.setHuman(true);
|
||||
|
||||
obj.getIsNonPrimitiveHuman();
|
||||
obj.setIsNonPrimitiveHuman(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//FILE: test.kt
|
||||
|
||||
class Test {
|
||||
fun run() {
|
||||
val obj = AccessorsTest()
|
||||
|
||||
obj.getAge()
|
||||
val age = obj.age
|
||||
|
||||
obj.isHuman()
|
||||
obj.setHuman(true)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -31,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);
|
||||
}
|
||||
|
||||
@TestMetadata("accessorsStripPrefix.kt")
|
||||
public void testAccessorsStripPrefix() throws Exception {
|
||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/accessorsStripPrefix.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("allArgsConstructor.kt")
|
||||
public void testAllArgsConstructor() throws Exception {
|
||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/allArgsConstructor.kt");
|
||||
|
||||
Reference in New Issue
Block a user