[lombok] Don't generate members that already exist

This commit is contained in:
Andrey Zinovyev
2021-03-28 18:35:13 +03:00
committed by TeamCityServer
parent d459cde010
commit 8011452c28
3 changed files with 44 additions and 9 deletions
@@ -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
@@ -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<SimpleFunctionDescriptor>
) {
val methods = getSyntheticParts(thisDescriptor).methods.filter { it.name == name }
result.addAll(methods)
addNonExistent(result, methods)
}
override fun getStaticFunctionNames(thisDescriptor: ClassDescriptor): List<Name> =
@@ -49,12 +50,12 @@ class LombokSyntheticJavaPartsProvider(private val config: LombokConfig) : Synth
override fun generateStaticFunctions(thisDescriptor: ClassDescriptor, name: Name, result: MutableCollection<SimpleFunctionDescriptor>) {
val functions = getSyntheticParts(thisDescriptor).staticFunctions.filter { it.name == name }
result.addAll(functions)
addNonExistent(result, functions)
}
override fun generateConstructors(thisDescriptor: ClassDescriptor, result: MutableList<ClassConstructorDescriptor>) {
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 <T : FunctionDescriptor> addNonExistent(result: MutableCollection<T>, toAdd: List<T>) {
if (toAdd.isEmpty()) return
val index = mutableMapOf<Name, List<T>>()
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
}
}
}
@@ -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()