From 411441c3325b2018bd429ba41df301e6992f5492 Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Fri, 26 Mar 2021 17:48:38 +0300 Subject: [PATCH] [lombok] Generic classes support --- .../lombok/lombok-compiler-plugin/README.md | 2 +- .../processor/AbstractConstructorProcessor.kt | 7 ++-- .../kotlin/lombok/utils/descriptorUtils.kt | 10 +++-- .../testData/compile/genericsAccessors.kt | 38 +++++++++++++++++++ .../testData/compile/genericsConstructors.kt | 29 ++++++++++++++ .../compile/genericsConstructorsStatic.kt | 29 ++++++++++++++ .../testData/compile/getters.kt | 2 +- .../lombok/LombokCompileTestGenerated.java | 15 ++++++++ 8 files changed, 122 insertions(+), 10 deletions(-) create mode 100644 plugins/lombok/lombok-compiler-plugin/testData/compile/genericsAccessors.kt create mode 100644 plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructors.kt create mode 100644 plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructorsStatic.kt diff --git a/plugins/lombok/lombok-compiler-plugin/README.md b/plugins/lombok/lombok-compiler-plugin/README.md index 52b95d82452..867d1fe5504 100644 --- a/plugins/lombok/lombok-compiler-plugin/README.md +++ b/plugins/lombok/lombok-compiler-plugin/README.md @@ -36,7 +36,7 @@ Features support: Other todos: - - [ ] Generic classes + - [x] Generic classes - [ ] Actually run compiled code - [ ] Don't generate members that already exist (if having a duplicate is a problem) - [ ] Gradle integration (as subplugin or just a way to enable lombok support) diff --git a/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/processor/AbstractConstructorProcessor.kt b/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/processor/AbstractConstructorProcessor.kt index 0fb95c5977f..a37611ee9db 100644 --- a/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/processor/AbstractConstructorProcessor.kt +++ b/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/processor/AbstractConstructorProcessor.kt @@ -8,13 +8,11 @@ package org.jetbrains.kotlin.lombok.processor import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl -import org.jetbrains.kotlin.lombok.config.AllArgsConstructor import org.jetbrains.kotlin.lombok.config.AnnotationCompanion import org.jetbrains.kotlin.lombok.config.ConstructorAnnotation import org.jetbrains.kotlin.lombok.utils.ValueParameter -import org.jetbrains.kotlin.lombok.utils.createConstructor +import org.jetbrains.kotlin.lombok.utils.createJavaConstructor import org.jetbrains.kotlin.lombok.utils.createFunction -import org.jetbrains.kotlin.lombok.utils.getJavaFields import org.jetbrains.kotlin.name.Name abstract class AbstractConstructorProcessor( @@ -28,7 +26,7 @@ abstract class AbstractConstructorProcessor( val result = annotationCompanion.getOrNull(classDescriptor)?.let { annotation -> if (annotation.staticName == null) { - val constructor = classDescriptor.createConstructor( + val constructor = classDescriptor.createJavaConstructor( valueParameters = valueParameters, visibility = annotation.visibility ) @@ -38,6 +36,7 @@ abstract class AbstractConstructorProcessor( Name.identifier(annotation.staticName!!), valueParameters, classDescriptor.defaultType, + typeParameters = classDescriptor.declaredTypeParameters, visibility = annotation.visibility, receiver = null ) diff --git a/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/utils/descriptorUtils.kt b/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/utils/descriptorUtils.kt index 3d243e34531..cd41e090643 100644 --- a/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/utils/descriptorUtils.kt +++ b/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/utils/descriptorUtils.kt @@ -11,6 +11,7 @@ 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.descriptors.JavaClassConstructorDescriptor import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.KotlinType @@ -21,6 +22,7 @@ fun ClassDescriptor.createFunction( name: Name, valueParameters: List, returnType: KotlinType?, + typeParameters: List = emptyList(), modality: Modality? = Modality.OPEN, visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC, receiver: ReceiverParameterDescriptor? = this.thisAsReceiverParameter @@ -38,7 +40,7 @@ fun ClassDescriptor.createFunction( methodDescriptor.initialize( null, receiver, - mutableListOf(), + typeParameters, paramDescriptors, returnType, modality, @@ -47,11 +49,11 @@ fun ClassDescriptor.createFunction( return methodDescriptor } -fun ClassDescriptor.createConstructor( +fun ClassDescriptor.createJavaConstructor( valueParameters: List, visibility: DescriptorVisibility = DescriptorVisibilities.PUBLIC ): ClassConstructorDescriptor { - val constructor = ClassConstructorDescriptorImpl.create( + val constructor = JavaClassConstructorDescriptor.create( this, Annotations.EMPTY, false, @@ -61,7 +63,7 @@ fun ClassDescriptor.createConstructor( constructor.initialize( null, constructor.calculateDispatchReceiverParameter(), - emptyList(), + this.declaredTypeParameters, paramDescriptors, this.defaultType, Modality.OPEN, diff --git a/plugins/lombok/lombok-compiler-plugin/testData/compile/genericsAccessors.kt b/plugins/lombok/lombok-compiler-plugin/testData/compile/genericsAccessors.kt new file mode 100644 index 00000000000..5354e9a2920 --- /dev/null +++ b/plugins/lombok/lombok-compiler-plugin/testData/compile/genericsAccessors.kt @@ -0,0 +1,38 @@ +//FILE: GenericsTest.java + +import lombok.*; +import java.util.*; + +public class GenericsTest { + @Getter private int age = 10; + + @Getter @Setter private A fieldA; + + @Getter private B fieldB; + + @Setter private Map fieldC; + + static void test() { + val obj = new GenericsTest(); + int age = obj.getAge(); + String a = obj.getFieldA(); + obj.setFieldA("fooo"); + Boolean b = obj.getFieldB(); + obj.setFieldC(new HashMap()); + } + +} + + +//FILE: test.kt + +object Test { + fun usage() { + val obj = GenericsTest() + val age: Int = obj.getAge(); + val a: String = obj.getFieldA(); + obj.setFieldA("fooo"); + val b: Boolean = obj.getFieldB(); + obj.setFieldC(java.util.HashMap()); + } +} diff --git a/plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructors.kt b/plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructors.kt new file mode 100644 index 00000000000..4db9a4f58ea --- /dev/null +++ b/plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructors.kt @@ -0,0 +1,29 @@ +//FILE: ConstructorExample.java + +import lombok.*; + +@AllArgsConstructor +@RequiredArgsConstructor +public class ConstructorExample { + + @Getter @Setter private int age = 10; + + @Getter private final A name; + + private B otherField; + + static void javaUsage() { + val generated = new ConstructorExample(12, 42L, true); + val generatedReq = new ConstructorExample("234"); + } +} + + +//FILE: test.kt + +object Test { + fun usage() { + val generated = ConstructorExample(12, 42L, true) + val generatedReq = ConstructorExample("234"); + } +} diff --git a/plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructorsStatic.kt b/plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructorsStatic.kt new file mode 100644 index 00000000000..32ce1594250 --- /dev/null +++ b/plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructorsStatic.kt @@ -0,0 +1,29 @@ +//FILE: ConstructorExample.java + +import lombok.*; + +@AllArgsConstructor(staticName = "of") +@RequiredArgsConstructor(staticName = "of") +public class ConstructorExample { + + @Getter @Setter private int age = 10; + + @Getter private final A name; + + private B otherField; + + static void javaUsage() { + ConstructorExample generated = ConstructorExample.of(12, 42L, true); + ConstructorExample generatedReq = ConstructorExample.of("234"); + } +} + + +//FILE: test.kt + +object Test { + fun usage() { + val generated: ConstructorExample = ConstructorExample.of(12, 42L, true) + val generatedReq: ConstructorExample = ConstructorExample.of("234"); + } +} diff --git a/plugins/lombok/lombok-compiler-plugin/testData/compile/getters.kt b/plugins/lombok/lombok-compiler-plugin/testData/compile/getters.kt index 9fe12beef18..2a2fa5424c9 100644 --- a/plugins/lombok/lombok-compiler-plugin/testData/compile/getters.kt +++ b/plugins/lombok/lombok-compiler-plugin/testData/compile/getters.kt @@ -28,7 +28,7 @@ object Test { val getter = obj.getAge() val property = obj.age - //todo kotlin doesn't see isBoolean methods as properties + //todo kotlin doesn't see isBoolean methods as property // obj.primitiveBoolean obj.isPrimitiveBoolean() diff --git a/plugins/lombok/lombok-compiler-plugin/tests/org/jetbrains/kotlin/lombok/LombokCompileTestGenerated.java b/plugins/lombok/lombok-compiler-plugin/tests/org/jetbrains/kotlin/lombok/LombokCompileTestGenerated.java index 063e2b9f891..97911d7f65d 100644 --- a/plugins/lombok/lombok-compiler-plugin/tests/org/jetbrains/kotlin/lombok/LombokCompileTestGenerated.java +++ b/plugins/lombok/lombok-compiler-plugin/tests/org/jetbrains/kotlin/lombok/LombokCompileTestGenerated.java @@ -76,6 +76,21 @@ public class LombokCompileTestGenerated extends AbstractLombokCompileTest { runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/requiredArgsConstructorStatic.kt"); } + @TestMetadata("genericsAccessors.kt") + public void testGenericsAccessors() throws Exception { + runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/genericsAccessors.kt"); + } + + @TestMetadata("genericsConstructors.kt") + public void testGenericsConstructors() throws Exception { + runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructors.kt"); + } + + @TestMetadata("genericsConstructorsStatic.kt") + public void testGenericsConstructorsStatic() throws Exception { + runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/genericsConstructorsStatic.kt"); + } + @TestMetadata("getters.kt") public void testGetters() throws Exception { runTest("plugins/lombok/lombok-compiler-plugin/testData/compile/getters.kt");