[FE 1.0] Allow generation of nested classes for java classes from plugins

This commit is contained in:
Dmitriy Novozhilov
2022-08-05 11:46:08 +03:00
parent 5adfbfc73f
commit 6fde784b55
13 changed files with 331 additions and 32 deletions
@@ -9,6 +9,7 @@ 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.LazyJavaResolverContext
import org.jetbrains.kotlin.lombok.config.LombokConfig
import org.jetbrains.kotlin.lombok.processor.*
import org.jetbrains.kotlin.lombok.utils.getJavaClass
@@ -20,6 +21,7 @@ import java.util.*
* Provides synthetic parts to java classes (from current compilation unit), which will be generated by lombok AnnotationProcessor
* So kotlin can reference lombok members.
*/
@Suppress("IncorrectFormatting") // KTIJ-22227
class LombokSyntheticJavaPartsProvider(config: LombokConfig) : SyntheticJavaPartsProvider {
private val processors = listOf(
@@ -38,9 +40,11 @@ class LombokSyntheticJavaPartsProvider(config: LombokConfig) : SyntheticJavaPart
*/
private val partsCache: MutableMap<ClassDescriptor, SyntheticParts> = HashMap()
context(LazyJavaResolverContext)
override fun getMethodNames(thisDescriptor: ClassDescriptor): List<Name> =
getSyntheticParts(thisDescriptor).methods.map { it.name }
context(LazyJavaResolverContext)
override fun generateMethods(
thisDescriptor: ClassDescriptor,
name: Name,
@@ -50,26 +54,45 @@ class LombokSyntheticJavaPartsProvider(config: LombokConfig) : SyntheticJavaPart
addNonExistent(result, methods)
}
context(LazyJavaResolverContext)
override fun getStaticFunctionNames(thisDescriptor: ClassDescriptor): List<Name> =
getSyntheticParts(thisDescriptor).staticFunctions.map { it.name }
context(LazyJavaResolverContext)
override fun generateStaticFunctions(thisDescriptor: ClassDescriptor, name: Name, result: MutableCollection<SimpleFunctionDescriptor>) {
val functions = getSyntheticParts(thisDescriptor).staticFunctions.filter { it.name == name }
addNonExistent(result, functions)
}
context(LazyJavaResolverContext)
override fun generateConstructors(thisDescriptor: ClassDescriptor, result: MutableList<ClassConstructorDescriptor>) {
val constructors = getSyntheticParts(thisDescriptor).constructors
addNonExistent(result, constructors)
}
context(LazyJavaResolverContext)
override fun getNestedClassNames(thisDescriptor: ClassDescriptor): List<Name> {
return getSyntheticParts(thisDescriptor).classes.map { it.name }
}
context(LazyJavaResolverContext)
override fun generateNestedClass(
thisDescriptor: ClassDescriptor,
name: Name,
result: MutableList<ClassDescriptor>
) {
result += getSyntheticParts(thisDescriptor).classes.filter { it.name == name }
}
context(LazyJavaResolverContext)
private fun getSyntheticParts(descriptor: ClassDescriptor): SyntheticParts =
descriptor.getJavaClass()?.let { _ ->
descriptor.getJavaClass()?.let {
partsCache.getOrPut(descriptor) {
computeSyntheticParts(descriptor)
}
} ?: SyntheticParts.Empty
context(LazyJavaResolverContext)
private fun computeSyntheticParts(descriptor: ClassDescriptor): SyntheticParts {
val builder = SyntheticPartsBuilder()
processors.forEach { it.contribute(descriptor, builder) }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.lombok.processor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.ConstructorAnnotation
import org.jetbrains.kotlin.lombok.utils.LombokValueParameter
import org.jetbrains.kotlin.lombok.utils.createFunction
@@ -15,6 +16,8 @@ import org.jetbrains.kotlin.name.Name
abstract class AbstractConstructorProcessor<A : ConstructorAnnotation> : Processor {
context(LazyJavaResolverContext)
@Suppress("IncorrectFormatting") // KTIJ-22227
override fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder) {
getAnnotation(classDescriptor)?.let { annotation ->
val valueParameters = getPropertiesForParameters(classDescriptor).map { property ->
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.lombok.processor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.lombok.config.*
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Accessors
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.Getter
@@ -18,6 +19,8 @@ import org.jetbrains.kotlin.name.Name
class GetterProcessor(private val config: LombokConfig) : Processor {
context(LazyJavaResolverContext)
@Suppress("IncorrectFormatting") // KTIJ-22227
override fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder) {
val globalAccessors = Accessors.get(classDescriptor, config)
val clGetter =
@@ -6,12 +6,14 @@
package org.jetbrains.kotlin.lombok.processor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
/**
* Generates synthetic parts for [ClassDescriptor]
*/
interface Processor {
context(LazyJavaResolverContext)
fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder)
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.lombok.processor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.lombok.config.*
import org.jetbrains.kotlin.lombok.utils.*
import org.jetbrains.kotlin.name.Name
@@ -16,6 +17,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
class SetterProcessor(private val config: LombokConfig) : Processor {
context(LazyJavaResolverContext)
@Suppress("IncorrectFormatting") // KTIJ-22227
override fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder) {
//lombok doesn't generate setters for enums
if (classDescriptor.kind == ClassKind.ENUM_CLASS) return
@@ -6,18 +6,21 @@
package org.jetbrains.kotlin.lombok.processor
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
class SyntheticParts(
val methods: List<SimpleFunctionDescriptor> = emptyList(),
val staticFunctions: List<SimpleFunctionDescriptor> = emptyList(),
val constructors: List<ClassConstructorDescriptor> = emptyList()
val constructors: List<ClassConstructorDescriptor> = emptyList(),
val classes: List<ClassDescriptor> = emptyList(),
) {
operator fun plus(other: SyntheticParts): SyntheticParts = SyntheticParts(
methods + other.methods,
staticFunctions + other.staticFunctions,
constructors + other.constructors
constructors + other.constructors,
classes + other.classes
)
companion object {
@@ -29,6 +32,7 @@ class SyntheticPartsBuilder {
private val methods = mutableListOf<SimpleFunctionDescriptor>()
private val staticFunctions = mutableListOf<SimpleFunctionDescriptor>()
private val constructors = mutableListOf<ClassConstructorDescriptor>()
private val classes = mutableListOf<ClassDescriptor>()
fun addMethod(method: SimpleFunctionDescriptor) {
methods += method
@@ -42,5 +46,9 @@ class SyntheticPartsBuilder {
constructors += constructor
}
fun build(): SyntheticParts = SyntheticParts(methods, staticFunctions, constructors)
fun addClass(clazz: ClassDescriptor) {
classes += clazz
}
fun build(): SyntheticParts = SyntheticParts(methods, staticFunctions, constructors, classes)
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.lombok.processor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.lombok.config.AccessLevel
import org.jetbrains.kotlin.lombok.config.LombokAnnotations.With
import org.jetbrains.kotlin.lombok.config.toDescriptorVisibility
@@ -16,6 +17,9 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.typeUtil.isBoolean
class WithProcessor : Processor {
context(LazyJavaResolverContext)
@Suppress("IncorrectFormatting") // KTIJ-22227
override fun contribute(classDescriptor: ClassDescriptor, partsBuilder: SyntheticPartsBuilder) {
val clWith = With.getOrNull(classDescriptor)