From 8011452c28efe683ac60035a80647254c48c19cb Mon Sep 17 00:00:00 2001 From: Andrey Zinovyev Date: Sun, 28 Mar 2021 18:35:13 +0300 Subject: [PATCH] [lombok] Don't generate members that already exist --- .../lombok/lombok-compiler-plugin/README.md | 3 +- .../LombokSyntheticJavaPartsProvider.kt | 41 +++++++++++++++++-- .../testData/compile/clashAccessors.kt | 9 ++-- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/plugins/lombok/lombok-compiler-plugin/README.md b/plugins/lombok/lombok-compiler-plugin/README.md index 44603cc7b6c..b19500d9bcb 100644 --- a/plugins/lombok/lombok-compiler-plugin/README.md +++ b/plugins/lombok/lombok-compiler-plugin/README.md @@ -39,9 +39,10 @@ Features support: Other todos: - [x] Generic classes - [x] Actually run compiled code - - [ ] Don't generate members that already exist (if having a duplicate is a problem) + - [x] 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) - [ ] Maven integration (as subplugin or just a way to enable lombok support) + - [ ] Nullability from annotations. Check if it is inherited from variable definition diff --git a/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/LombokSyntheticJavaPartsProvider.kt b/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/LombokSyntheticJavaPartsProvider.kt index c43ae4e48b3..76c0d32af76 100644 --- a/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/LombokSyntheticJavaPartsProvider.kt +++ b/plugins/lombok/lombok-compiler-plugin/src/org/jetbrains/kotlin/lombok/LombokSyntheticJavaPartsProvider.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.lombok import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl @@ -41,7 +42,7 @@ class LombokSyntheticJavaPartsProvider(private val config: LombokConfig) : Synth result: MutableCollection ) { val methods = getSyntheticParts(thisDescriptor).methods.filter { it.name == name } - result.addAll(methods) + addNonExistent(result, methods) } override fun getStaticFunctionNames(thisDescriptor: ClassDescriptor): List = @@ -49,12 +50,12 @@ class LombokSyntheticJavaPartsProvider(private val config: LombokConfig) : Synth override fun generateStaticFunctions(thisDescriptor: ClassDescriptor, name: Name, result: MutableCollection) { val functions = getSyntheticParts(thisDescriptor).staticFunctions.filter { it.name == name } - result.addAll(functions) + addNonExistent(result, functions) } override fun generateConstructors(thisDescriptor: ClassDescriptor, result: MutableList) { val constructors = getSyntheticParts(thisDescriptor).constructors - result.addAll(constructors) + addNonExistent(result, constructors) } private fun extractClass(descriptor: ClassDescriptor): JavaClassImpl? = @@ -70,5 +71,39 @@ class LombokSyntheticJavaPartsProvider(private val config: LombokConfig) : Synth private fun computeSyntheticParts(descriptor: ClassDescriptor, jClass: JavaClassImpl): Parts = processors.map { it.contribute(descriptor, jClass) }.reduce { a, b -> a + b } + private fun addNonExistent(result: MutableCollection, toAdd: List) { + if (toAdd.isEmpty()) return + val index = mutableMapOf>() + + fun addToIndex(f: T) { + index.merge(f.name, listOf(f)) { a, b -> a + b} + } + + result.forEach(::addToIndex) + + toAdd.forEach { f -> + val existing = index.getOrDefault(f.name, emptyList()) + if (existing.none { sameSignature (it, f) } ) { + result += f + addToIndex(f) + } + } + } + + + companion object { + + /** + * Lombok treat functions as having the same signature by arguments count only + */ + private fun sameSignature(a: FunctionDescriptor, b: FunctionDescriptor): Boolean { + val aVararg = a.valueParameters.any { it.varargElementType != null } + val bVararg = b.valueParameters.any { it.varargElementType != null } + return aVararg && bVararg || + aVararg && b.valueParameters.size >= (a.valueParameters.size - 1) || + bVararg && a.valueParameters.size >= (b.valueParameters.size - 1) || + a.valueParameters.size == b.valueParameters.size + } + } } diff --git a/plugins/lombok/lombok-compiler-plugin/testData/compile/clashAccessors.kt b/plugins/lombok/lombok-compiler-plugin/testData/compile/clashAccessors.kt index ff61f3b5399..0b9169279b1 100644 --- a/plugins/lombok/lombok-compiler-plugin/testData/compile/clashAccessors.kt +++ b/plugins/lombok/lombok-compiler-plugin/testData/compile/clashAccessors.kt @@ -11,7 +11,6 @@ public class SuperClass { } - //FILE: ClashTest.java import lombok.*; @@ -76,7 +75,7 @@ public class ChildClass extends ClashTest{ class KotlinChildClass : ClashTest() { - override fun getToOverride(): Int = super.getToOverride() + override fun getToOverride(): Int? = super.getToOverride() } @@ -85,10 +84,10 @@ class Test { val obj = ClashTest() obj.getAge() - //todo thats shouldn't work - obj.setAge(41) + //thats shouldn't work because lombok doesn't generate clashing method +// obj.setAge(41) +// obj.age = 12 val age = obj.age - obj.age = 12 obj.getName()