[lombok] Support @AllArgsConstructor
This commit is contained in:
committed by
TeamCityServer
parent
59f936fdef
commit
b336a335bf
@@ -25,7 +25,7 @@ Features support:
|
||||
|
||||
[~] [@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor](https://projectlombok.org/features/constructor)
|
||||
- [x] @NoArgsConstructor
|
||||
- [ ] @AllArgsConstructor
|
||||
- [x] @AllArgsConstructor
|
||||
- [ ] @RequiredArgsConstructor
|
||||
|
||||
[ ] [@Data](https://projectlombok.org/features/Data)
|
||||
|
||||
+2
-1
@@ -25,7 +25,8 @@ class LombokSyntheticJavaPartsProvider(private val config: LombokConfig) : Synth
|
||||
GetterProcessor(config),
|
||||
SetterProcessor(config),
|
||||
WithProcessor(config),
|
||||
NoArgsConstructorProcessor()
|
||||
NoArgsConstructorProcessor(),
|
||||
AllArgsConstructorProcessor()
|
||||
)
|
||||
|
||||
private val partsCache: MutableMap<ClassDescriptor, Parts> = WeakHashMap()
|
||||
|
||||
+18
-3
@@ -8,9 +8,9 @@ package org.jetbrains.kotlin.lombok.config
|
||||
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.*
|
||||
import org.jetbrains.kotlin.lombok.utils.LombokNames
|
||||
import org.jetbrains.kotlin.lombok.utils.getBooleanArgument
|
||||
import org.jetbrains.kotlin.lombok.utils.getStringArgument
|
||||
import org.jetbrains.kotlin.lombok.utils.getNonBlankStringArgument
|
||||
import org.jetbrains.kotlin.lombok.utils.getVisibility
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
@@ -82,7 +82,22 @@ data class NoArgsConstructor(
|
||||
override fun extract(annotation: AnnotationDescriptor): NoArgsConstructor =
|
||||
NoArgsConstructor(
|
||||
visibility = getVisibility(annotation),
|
||||
staticName = annotation.getStringArgument("staticName").trimToNull()
|
||||
staticName = annotation.getNonBlankStringArgument("staticName")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class AllArgsConstructor(
|
||||
val visibility: DescriptorVisibility,
|
||||
val staticName: String?
|
||||
) {
|
||||
companion object : AnnotationCompanion<AllArgsConstructor>() {
|
||||
override val name: FqName = LombokNames.ALL_ARGS_CONSTRUCTOR
|
||||
|
||||
override fun extract(annotation: AnnotationDescriptor): AllArgsConstructor =
|
||||
AllArgsConstructor(
|
||||
visibility = getVisibility(annotation),
|
||||
staticName = annotation.getNonBlankStringArgument("staticName")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.processor
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl
|
||||
import org.jetbrains.kotlin.lombok.config.AllArgsConstructor
|
||||
import org.jetbrains.kotlin.lombok.utils.ValueParameter
|
||||
import org.jetbrains.kotlin.lombok.utils.createConstructor
|
||||
import org.jetbrains.kotlin.lombok.utils.createFunction
|
||||
import org.jetbrains.kotlin.lombok.utils.getJavaFields
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class AllArgsConstructorProcessor : Processor {
|
||||
|
||||
override fun contribute(classDescriptor: ClassDescriptor, jClass: JavaClassImpl): Parts {
|
||||
|
||||
val valueParameters = classDescriptor.getJavaFields().map { property ->
|
||||
ValueParameter(property.name, property.type)
|
||||
}
|
||||
|
||||
val result = AllArgsConstructor.getOrNull(classDescriptor)?.let { annotation ->
|
||||
if (annotation.staticName == null) {
|
||||
val constructor = classDescriptor.createConstructor(
|
||||
valueParameters = valueParameters,
|
||||
visibility = annotation.visibility
|
||||
)
|
||||
Parts(constructors = listOfNotNull(constructor))
|
||||
} else {
|
||||
val function = classDescriptor.createFunction(
|
||||
Name.identifier(annotation.staticName),
|
||||
valueParameters,
|
||||
classDescriptor.defaultType,
|
||||
visibility = annotation.visibility,
|
||||
receiver = null
|
||||
)
|
||||
Parts(staticFunctions = listOf(function))
|
||||
}
|
||||
}
|
||||
return result ?: Parts.Empty
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.lombok.config.Getter
|
||||
import org.jetbrains.kotlin.lombok.config.LombokConfig
|
||||
import org.jetbrains.kotlin.lombok.utils.collectWithNotNull
|
||||
import org.jetbrains.kotlin.lombok.utils.createFunction
|
||||
import org.jetbrains.kotlin.lombok.utils.getVariables
|
||||
import org.jetbrains.kotlin.lombok.utils.getJavaFields
|
||||
import org.jetbrains.kotlin.lombok.utils.toPreparedBase
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
@@ -30,7 +30,7 @@ class GetterProcessor(private val config: LombokConfig) : Processor {
|
||||
val clGetter = Getter.getOrNull(classDescriptor)
|
||||
|
||||
val functions = classDescriptor
|
||||
.getVariables()
|
||||
.getJavaFields()
|
||||
.collectWithNotNull { Getter.getOrNull(it) ?: clGetter }
|
||||
.mapNotNull { (field, annotation) -> createGetter(classDescriptor, field, annotation, clAccessors) }
|
||||
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ class SetterProcessor(private val config: LombokConfig) : Processor {
|
||||
val clSetter = Setter.getOrNull(classDescriptor)
|
||||
|
||||
val functions = classDescriptor
|
||||
.getVariables()
|
||||
.getJavaFields()
|
||||
.collectWithNotNull { field -> Setter.getOrNull(field) ?: clSetter.takeIf { field.isVar } }
|
||||
.mapNotNull { (field, setter) -> createSetter(classDescriptor, field, setter, clAccessors) }
|
||||
return Parts(functions)
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ class WithProcessor(private val config: LombokConfig) : Processor {
|
||||
val clWith = With.getOrNull(classDescriptor)
|
||||
|
||||
val functions = classDescriptor
|
||||
.getVariables()
|
||||
.getJavaFields()
|
||||
.collectWithNotNull { With.getOrNull(it) ?: clWith }
|
||||
.mapNotNull { (field, annotation) -> createWith(classDescriptor, field, annotation) }
|
||||
|
||||
|
||||
+1
@@ -14,5 +14,6 @@ object LombokNames {
|
||||
val SETTER = FqName("lombok.Setter")
|
||||
val WITH = FqName("lombok.With")
|
||||
val NO_ARGS_CONSTRUCTOR = FqName("lombok.NoArgsConstructor")
|
||||
val ALL_ARGS_CONSTRUCTOR = FqName("lombok.AllArgsConstructor")
|
||||
|
||||
}
|
||||
|
||||
+6
-3
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.resolve.constants.BooleanValue
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
|
||||
internal fun getVisibility(annotation: AnnotationDescriptor, field: String = "value"): DescriptorVisibility {
|
||||
fun getVisibility(annotation: AnnotationDescriptor, field: String = "value"): DescriptorVisibility {
|
||||
val value = annotation.getStringArgument(field) ?: "PUBLIC"
|
||||
val visibility = when (value) {
|
||||
"PUBLIC" -> Visibilities.Public
|
||||
@@ -27,7 +27,7 @@ internal fun getVisibility(annotation: AnnotationDescriptor, field: String = "va
|
||||
return DescriptorVisibilities.toDescriptorVisibility(visibility)
|
||||
}
|
||||
|
||||
internal fun AnnotationDescriptor.getStringArgument(argumentName: String): String? {
|
||||
fun AnnotationDescriptor.getStringArgument(argumentName: String): String? {
|
||||
val argument = allValueArguments[Name.identifier(argumentName)]
|
||||
?: return null
|
||||
|
||||
@@ -38,7 +38,10 @@ internal fun AnnotationDescriptor.getStringArgument(argumentName: String): Strin
|
||||
}
|
||||
}
|
||||
|
||||
internal fun AnnotationDescriptor.getBooleanArgument(argumentName: String, default: Boolean = false): Boolean {
|
||||
fun AnnotationDescriptor.getNonBlankStringArgument(argumentName: String): String? =
|
||||
getStringArgument(argumentName).trimToNull()
|
||||
|
||||
fun AnnotationDescriptor.getBooleanArgument(argumentName: String, default: Boolean = false): Boolean {
|
||||
val argument = allValueArguments[Name.identifier(argumentName)]
|
||||
?: return default
|
||||
|
||||
|
||||
+6
-5
@@ -11,12 +11,13 @@ import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
internal data class ValueParameter(val name: Name, val type: KotlinType)
|
||||
data class ValueParameter(val name: Name, val type: KotlinType)
|
||||
|
||||
internal fun ClassDescriptor.createFunction(
|
||||
fun ClassDescriptor.createFunction(
|
||||
name: Name,
|
||||
valueParameters: List<ValueParameter>,
|
||||
returnType: KotlinType?,
|
||||
@@ -46,7 +47,7 @@ internal fun ClassDescriptor.createFunction(
|
||||
return methodDescriptor
|
||||
}
|
||||
|
||||
internal fun ClassDescriptor.createConstructor(
|
||||
fun ClassDescriptor.createConstructor(
|
||||
valueParameters: List<ValueParameter>,
|
||||
visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC
|
||||
): ClassConstructorDescriptor {
|
||||
@@ -85,8 +86,8 @@ private fun CallableDescriptor.makeValueParameter(param: ValueParameter, index:
|
||||
)
|
||||
}
|
||||
|
||||
internal fun ClassDescriptor.getVariables(): List<PropertyDescriptor> =
|
||||
fun ClassDescriptor.getJavaFields(): List<PropertyDescriptor> =
|
||||
this.unsubstitutedMemberScope.getVariableNames()
|
||||
.map {
|
||||
this.unsubstitutedMemberScope.getContributedVariables(it, NoLookupLocation.FROM_SYNTHETIC_SCOPE).single()
|
||||
}
|
||||
}.filter { it.isJavaField }
|
||||
|
||||
+1
-1
@@ -7,4 +7,4 @@ package org.jetbrains.kotlin.lombok.utils
|
||||
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||
|
||||
internal fun toPreparedBase(name: String): String = name.capitalizeAsciiOnly()
|
||||
fun toPreparedBase(name: String): String = name.capitalizeAsciiOnly()
|
||||
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
package org.jetbrains.kotlin.lombok.utils
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
internal fun <E, R> Collection<E>.collectWithNotNull(f: (E) -> R?): List<Pair<E, R>> =
|
||||
fun <E, R> Collection<E>.collectWithNotNull(f: (E) -> R?): List<Pair<E, R>> =
|
||||
map { it to f(it) }.filter { it.second != null } as List<Pair<E, R>>
|
||||
|
||||
internal fun String?.trimToNull(): String? = this?.trim()?.takeIf { it.isNotEmpty() }
|
||||
fun String?.trimToNull(): String? = this?.trim()?.takeIf { it.isNotEmpty() }
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
//FILE: ConstructorExample.java
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class ConstructorExample {
|
||||
|
||||
@Getter @Setter private int age = 10;
|
||||
|
||||
@Getter(AccessLevel.PROTECTED) private String name;
|
||||
|
||||
private boolean otherField;
|
||||
|
||||
static void javaUsage() {
|
||||
val generated = new ConstructorExample(12, "sdf", true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//FILE: test.kt
|
||||
|
||||
object Test {
|
||||
fun usage() {
|
||||
val generated = ConstructorExample(12, "sdf", true)
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
//FILE: ConstructorExample.java
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@AllArgsConstructor(staticName = "of")
|
||||
public class ConstructorExample {
|
||||
|
||||
@Getter @Setter private int age = 10;
|
||||
|
||||
@Getter(AccessLevel.PROTECTED) private String name;
|
||||
|
||||
private boolean otherField;
|
||||
|
||||
public ConstructorExample(String arg) {
|
||||
|
||||
}
|
||||
|
||||
static void javaUsage() {
|
||||
ConstructorExample existing = new ConstructorExample("existing");
|
||||
ConstructorExample generated = ConstructorExample.of(45, "234", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//FILE: test.kt
|
||||
|
||||
object Test {
|
||||
fun usage() {
|
||||
val existing: ConstructorExample = ConstructorExample("existing")
|
||||
val generated: ConstructorExample = ConstructorExample.of(45, "234", false)
|
||||
}
|
||||
}
|
||||
+10
@@ -36,6 +36,16 @@ public class LombokCompileTestGenerated extends AbstractLombokCompileTest {
|
||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/configSimple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("allArgsConstructor.kt")
|
||||
public void testAllArgsConstructor() throws Exception {
|
||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/allArgsConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("allArgsConstructorStatic.kt")
|
||||
public void testAllArgsConstructorStatic() throws Exception {
|
||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/allArgsConstructorStatic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("gettersClassLevel.kt")
|
||||
public void testGettersClassLevel() throws Exception {
|
||||
runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/gettersClassLevel.kt");
|
||||
|
||||
Reference in New Issue
Block a user