[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)
|
[~] [@NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor](https://projectlombok.org/features/constructor)
|
||||||
- [x] @NoArgsConstructor
|
- [x] @NoArgsConstructor
|
||||||
- [ ] @AllArgsConstructor
|
- [x] @AllArgsConstructor
|
||||||
- [ ] @RequiredArgsConstructor
|
- [ ] @RequiredArgsConstructor
|
||||||
|
|
||||||
[ ] [@Data](https://projectlombok.org/features/Data)
|
[ ] [@Data](https://projectlombok.org/features/Data)
|
||||||
|
|||||||
+2
-1
@@ -25,7 +25,8 @@ class LombokSyntheticJavaPartsProvider(private val config: LombokConfig) : Synth
|
|||||||
GetterProcessor(config),
|
GetterProcessor(config),
|
||||||
SetterProcessor(config),
|
SetterProcessor(config),
|
||||||
WithProcessor(config),
|
WithProcessor(config),
|
||||||
NoArgsConstructorProcessor()
|
NoArgsConstructorProcessor(),
|
||||||
|
AllArgsConstructorProcessor()
|
||||||
)
|
)
|
||||||
|
|
||||||
private val partsCache: MutableMap<ClassDescriptor, Parts> = WeakHashMap()
|
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.DescriptorVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
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.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.lombok.utils.getVisibility
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
@@ -82,7 +82,22 @@ data class NoArgsConstructor(
|
|||||||
override fun extract(annotation: AnnotationDescriptor): NoArgsConstructor =
|
override fun extract(annotation: AnnotationDescriptor): NoArgsConstructor =
|
||||||
NoArgsConstructor(
|
NoArgsConstructor(
|
||||||
visibility = getVisibility(annotation),
|
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.config.LombokConfig
|
||||||
import org.jetbrains.kotlin.lombok.utils.collectWithNotNull
|
import org.jetbrains.kotlin.lombok.utils.collectWithNotNull
|
||||||
import org.jetbrains.kotlin.lombok.utils.createFunction
|
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.lombok.utils.toPreparedBase
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -30,7 +30,7 @@ class GetterProcessor(private val config: LombokConfig) : Processor {
|
|||||||
val clGetter = Getter.getOrNull(classDescriptor)
|
val clGetter = Getter.getOrNull(classDescriptor)
|
||||||
|
|
||||||
val functions = classDescriptor
|
val functions = classDescriptor
|
||||||
.getVariables()
|
.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, clAccessors) }
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ class SetterProcessor(private val config: LombokConfig) : Processor {
|
|||||||
val clSetter = Setter.getOrNull(classDescriptor)
|
val clSetter = Setter.getOrNull(classDescriptor)
|
||||||
|
|
||||||
val functions = classDescriptor
|
val functions = classDescriptor
|
||||||
.getVariables()
|
.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, clAccessors) }
|
||||||
return Parts(functions)
|
return Parts(functions)
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ class WithProcessor(private val config: LombokConfig) : Processor {
|
|||||||
val clWith = With.getOrNull(classDescriptor)
|
val clWith = With.getOrNull(classDescriptor)
|
||||||
|
|
||||||
val functions = classDescriptor
|
val functions = classDescriptor
|
||||||
.getVariables()
|
.getJavaFields()
|
||||||
.collectWithNotNull { With.getOrNull(it) ?: clWith }
|
.collectWithNotNull { With.getOrNull(it) ?: clWith }
|
||||||
.mapNotNull { (field, annotation) -> createWith(classDescriptor, field, annotation) }
|
.mapNotNull { (field, annotation) -> createWith(classDescriptor, field, annotation) }
|
||||||
|
|
||||||
|
|||||||
+1
@@ -14,5 +14,6 @@ object LombokNames {
|
|||||||
val SETTER = FqName("lombok.Setter")
|
val SETTER = FqName("lombok.Setter")
|
||||||
val WITH = FqName("lombok.With")
|
val WITH = FqName("lombok.With")
|
||||||
val NO_ARGS_CONSTRUCTOR = FqName("lombok.NoArgsConstructor")
|
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.EnumValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
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 value = annotation.getStringArgument(field) ?: "PUBLIC"
|
||||||
val visibility = when (value) {
|
val visibility = when (value) {
|
||||||
"PUBLIC" -> Visibilities.Public
|
"PUBLIC" -> Visibilities.Public
|
||||||
@@ -27,7 +27,7 @@ internal fun getVisibility(annotation: AnnotationDescriptor, field: String = "va
|
|||||||
return DescriptorVisibilities.toDescriptorVisibility(visibility)
|
return DescriptorVisibilities.toDescriptorVisibility(visibility)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun AnnotationDescriptor.getStringArgument(argumentName: String): String? {
|
fun AnnotationDescriptor.getStringArgument(argumentName: String): String? {
|
||||||
val argument = allValueArguments[Name.identifier(argumentName)]
|
val argument = allValueArguments[Name.identifier(argumentName)]
|
||||||
?: return null
|
?: 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)]
|
val argument = allValueArguments[Name.identifier(argumentName)]
|
||||||
?: return default
|
?: 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.SimpleFunctionDescriptorImpl
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
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.name.Name
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
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,
|
name: Name,
|
||||||
valueParameters: List<ValueParameter>,
|
valueParameters: List<ValueParameter>,
|
||||||
returnType: KotlinType?,
|
returnType: KotlinType?,
|
||||||
@@ -46,7 +47,7 @@ internal fun ClassDescriptor.createFunction(
|
|||||||
return methodDescriptor
|
return methodDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ClassDescriptor.createConstructor(
|
fun ClassDescriptor.createConstructor(
|
||||||
valueParameters: List<ValueParameter>,
|
valueParameters: List<ValueParameter>,
|
||||||
visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC
|
visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC
|
||||||
): ClassConstructorDescriptor {
|
): 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()
|
this.unsubstitutedMemberScope.getVariableNames()
|
||||||
.map {
|
.map {
|
||||||
this.unsubstitutedMemberScope.getContributedVariables(it, NoLookupLocation.FROM_SYNTHETIC_SCOPE).single()
|
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
|
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
|
package org.jetbrains.kotlin.lombok.utils
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@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>>
|
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");
|
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")
|
@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