[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
+3 -1
View File
@@ -364,7 +364,9 @@ val coreLibProjects by extra {
val projectsWithEnabledContextReceivers by extra {
listOf(
":compiler:fir:fir2ir"
":core:descriptors.jvm",
":compiler:fir:fir2ir",
":kotlin-lombok-compiler-plugin.k1",
)
}
@@ -77,7 +77,7 @@ class LazyJavaClassMemberScope(
addAll(declaredMemberIndex().getMethodNames())
addAll(declaredMemberIndex().getRecordComponentNames())
addAll(computeClassNames(kindFilter, nameFilter))
addAll(c.components.syntheticPartsProvider.getMethodNames(ownerDescriptor))
with(c) { addAll(c.components.syntheticPartsProvider.getMethodNames(ownerDescriptor)) }
}
internal val constructors = c.storageManager.createLazyValue {
@@ -98,7 +98,7 @@ class LazyJavaClassMemberScope(
}
}
c.components.syntheticPartsProvider.generateConstructors(ownerDescriptor, result)
with(c) { c.components.syntheticPartsProvider.generateConstructors(ownerDescriptor, result) }
c.components.signatureEnhancement.enhanceSignatures(
c,
@@ -496,7 +496,7 @@ class LazyJavaClassMemberScope(
result.add(resolveRecordComponentToFunctionDescriptor(declaredMemberIndex().findRecordComponentByName(name)!!))
}
c.components.syntheticPartsProvider.generateMethods(ownerDescriptor, name, result)
with(c) { c.components.syntheticPartsProvider.generateMethods(ownerDescriptor, name, result) }
}
private fun resolveRecordComponentToFunctionDescriptor(recordComponent: JavaRecordComponent): JavaMethodDescriptor {
@@ -803,31 +803,50 @@ class LazyJavaClassMemberScope(
jClass.innerClassNames.toSet()
}
private val generatedNestedClassNames = c.storageManager.createLazyValue {
with(c) { c.components.syntheticPartsProvider.getNestedClassNames(ownerDescriptor).toSet() }
}
private val enumEntryIndex = c.storageManager.createLazyValue {
jClass.fields.filter { it.isEnumEntry }.associateBy { f -> f.name }
}
private val nestedClasses = c.storageManager.createMemoizedFunctionWithNullableValues { name: Name ->
if (name !in nestedClassIndex()) {
val field = enumEntryIndex()[name]
if (field != null) {
val enumMemberNames: NotNullLazyValue<Set<Name>> = c.storageManager.createLazyValue {
getFunctionNames() + getVariableNames()
when (name) {
in nestedClassIndex() -> {
c.components.finder.findClass(
JavaClassFinder.Request(
ownerDescriptor.classId!!.createNestedClassId(name),
outerClass = jClass
)
)?.let {
LazyJavaClassDescriptor(c, ownerDescriptor, it)
.also(c.components.javaClassesTracker::reportClass)
}
EnumEntrySyntheticClassDescriptor.create(
c.storageManager, ownerDescriptor, name, enumMemberNames, c.resolveAnnotations(field),
c.components.sourceElementFactory.source(field)
)
} else null
} else {
c.components.finder.findClass(
JavaClassFinder.Request(
ownerDescriptor.classId!!.createNestedClassId(name),
outerClass = jClass
)
)?.let {
LazyJavaClassDescriptor(c, ownerDescriptor, it)
.also(c.components.javaClassesTracker::reportClass)
}
in generatedNestedClassNames() -> {
val classes = with(c) {
buildList { c.components.syntheticPartsProvider.generateNestedClass(ownerDescriptor, name, this) }
}
when (classes.size) {
0 -> null
1 -> classes.single()
else -> error("Multiple classes with same name are generated: $classes")
}
}
else -> {
val field = enumEntryIndex()[name]
if (field != null) {
val enumMemberNames: NotNullLazyValue<Set<Name>> = c.storageManager.createLazyValue {
getFunctionNames() + getVariableNames()
}
EnumEntrySyntheticClassDescriptor.create(
c.storageManager, ownerDescriptor, name, enumMemberNames, c.resolveAnnotations(field),
c.components.sourceElementFactory.source(field)
)
} else null
}
}
}
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils.resolveOverridesForStaticMembers
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.descriptors.getParentJavaStaticClassScope
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.structure.JavaClass
@@ -37,7 +38,7 @@ import org.jetbrains.kotlin.utils.DFS
class LazyJavaStaticClassScope(
c: LazyJavaResolverContext,
private val jClass: JavaClass,
override val ownerDescriptor: LazyJavaClassDescriptor
override val ownerDescriptor: JavaClassDescriptor
) : LazyJavaStaticScope(c) {
override fun computeMemberIndex() = ClassDeclaredMemberIndex(jClass) { it.isStatic }
@@ -48,7 +49,7 @@ class LazyJavaStaticClassScope(
if (jClass.isEnum) {
addAll(listOf(StandardNames.ENUM_VALUE_OF, StandardNames.ENUM_VALUES))
}
addAll(c.components.syntheticPartsProvider.getStaticFunctionNames(ownerDescriptor))
with(c) { addAll(c.components.syntheticPartsProvider.getStaticFunctionNames(ownerDescriptor)) }
}
override fun computePropertyNames(kindFilter: DescriptorKindFilter, nameFilter: ((Name) -> Boolean)?) =
@@ -83,7 +84,7 @@ class LazyJavaStaticClassScope(
}
override fun computeImplicitlyDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name) {
c.components.syntheticPartsProvider.generateStaticFunctions(ownerDescriptor, name, result)
with(c) { c.components.syntheticPartsProvider.generateStaticFunctions(ownerDescriptor, name, result) }
}
override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
@@ -0,0 +1,202 @@
/*
* Copyright 2000-2018 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.load.java.lazy.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AbstractClassDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.childForClassOrPackage
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.scopes.InnerClassesScopeWrapper
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.ClassTypeConstructorImpl
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
class SyntheticJavaClassDescriptor(
private val outerContext: LazyJavaResolverContext,
name: Name,
private val outerClass: ClassDescriptor,
private val classKind: ClassKind,
private val modality: Modality,
private val visibility: DescriptorVisibility,
private val isInner: Boolean,
private val isRecord: Boolean,
override val annotations: Annotations,
private val declaredTypeParameters: List<TypeParameterDescriptor>,
private val sealedSubclasses: Collection<ClassDescriptor>,
supertypes: List<KotlinType>,
val attributes: Map<String, Any?>
) : AbstractClassDescriptor(
outerContext.storageManager,
name
), JavaClassDescriptor {
companion object {
@JvmStatic
private val PUBLIC_METHOD_NAMES_IN_OBJECT = setOf("equals", "hashCode", "getClass", "wait", "notify", "notifyAll", "toString")
}
private val jClass = FakeJavaClass()
private val c: LazyJavaResolverContext = outerContext.childForClassOrPackage(this)
override fun getKind(): ClassKind = classKind
override fun getModality(): Modality = modality
override fun isRecord(): Boolean = isRecord
override fun getVisibility(): DescriptorVisibility = visibility
override fun isInner() = isInner
override fun isData() = false
override fun isInline() = false
override fun isCompanionObject() = false
override fun isExpect() = false
override fun isActual() = false
override fun isFun() = false
override fun isValue() = false
private val typeConstructor = ClassTypeConstructorImpl(this, declaredTypeParameters, supertypes, c.storageManager)
override fun getTypeConstructor(): TypeConstructor = typeConstructor
private val unsubstitutedMemberScope =
LazyJavaClassMemberScope(c, this, jClass, skipRefinement = true)
private val scopeHolder =
ScopesHolderForClass.create(this, c.storageManager, c.components.kotlinTypeChecker.kotlinTypeRefiner) {
LazyJavaClassMemberScope(
c, this, jClass,
skipRefinement = true,
mainScope = unsubstitutedMemberScope
)
}
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner) = scopeHolder.getScope(kotlinTypeRefiner)
private val innerClassesScope = InnerClassesScopeWrapper(unsubstitutedMemberScope)
override fun getUnsubstitutedInnerClassesScope(): MemberScope = innerClassesScope
private val staticScope = LazyJavaStaticClassScope(c, jClass, this)
override fun getStaticScope(): MemberScope = staticScope
override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? = null
override fun getCompanionObjectDescriptor(): ClassDescriptor? = null
override fun getUnsubstitutedMemberScope() = super.getUnsubstitutedMemberScope() as LazyJavaClassMemberScope
override fun getConstructors() = unsubstitutedMemberScope.constructors()
override fun getDeclaredTypeParameters(): List<TypeParameterDescriptor> = declaredTypeParameters
override fun getDefaultFunctionTypeForSamInterface(): SimpleType? =
c.components.samConversionResolver.resolveFunctionTypeIfSamInterface(this)
override fun isDefinitelyNotSamInterface(): Boolean {
if (classKind != ClassKind.INTERFACE) return true
val candidates = jClass.methods.filter { it.isAbstract && it.typeParameters.isEmpty() }
// From the definition of function interfaces in the Java specification (pt. 9.8):
// "methods that are members of I that do not have the same signature as any public instance method of the class Object"
// It means that if an interface declares `int hashCode()` then the method won't be taken into account when
// checking if the interface is SAM.
// We make here a conservative check just filtering out methods by name.
// If we ignore a method with wrong signature (different from one in Object) it's not very bad,
// we'll just say that the interface MAY BE a SAM when it's not and then more detailed check will be applied.
if (candidates.count { it.name.identifier !in PUBLIC_METHOD_NAMES_IN_OBJECT } > 1) return true
// If we have default methods the interface could be a SAM even while a super interface has more than one abstract method
if (jClass.methods.any { !it.isAbstract && it.typeParameters.isEmpty() }) return false
// Check if any of the super-interfaces contain too many methods to be a SAM
return typeConstructor.supertypes.any {
it.constructor.declarationDescriptor.safeAs<SyntheticJavaClassDescriptor>()?.isDefinitelyNotSamInterface == true
}
}
override fun getSealedSubclasses(): Collection<ClassDescriptor> = sealedSubclasses
override fun getValueClassRepresentation(): ValueClassRepresentation<SimpleType>? = null
override fun getContainingDeclaration(): DeclarationDescriptor {
return outerClass
}
private val sourceElement = c.components.sourceElementFactory.source(jClass)
override fun getSource(): SourceElement = sourceElement
override fun isExternal(): Boolean = false
override fun toString() = "Lazy Java class ${this.fqNameUnsafe}"
private inner class FakeJavaClass : JavaClass {
override val name: Name
get() = this@SyntheticJavaClassDescriptor.name
override val isFromSource: Boolean
get() = false
override val annotations: Collection<JavaAnnotation>
get() = emptyList()
override val isDeprecatedInJavaDoc: Boolean
get() = false
override fun findAnnotation(fqName: FqName): JavaAnnotation? = null
override val isAbstract: Boolean
get() = modality == Modality.ABSTRACT
override val isStatic: Boolean
get() = !isInner
override val isFinal: Boolean
get() = modality == Modality.FINAL
override val visibility: Visibility
get() = this@SyntheticJavaClassDescriptor.visibility.delegate
override val typeParameters: List<JavaTypeParameter>
get() = emptyList()
override val fqName: FqName
get() = this@SyntheticJavaClassDescriptor.fqNameSafe
override val supertypes: Collection<JavaClassifierType>
get() = emptyList()
override val innerClassNames: Collection<Name>
get() = emptyList()
override fun findInnerClass(name: Name): JavaClass? = null
override val outerClass: JavaClass?
get() = null
override val isInterface: Boolean
get() = classKind == ClassKind.INTERFACE
override val isAnnotationType: Boolean
get() = classKind == ClassKind.ANNOTATION_CLASS
override val isEnum: Boolean
get() = classKind == ClassKind.ENUM_CLASS
override val isRecord: Boolean
get() = this@SyntheticJavaClassDescriptor.isRecord
override val isSealed: Boolean
get() = modality == Modality.SEALED
override val permittedTypes: Collection<JavaClassifierType>
get() = emptyList()
override val lightClassOriginKind: LightClassOriginKind?
get() = null
override val methods: Collection<JavaMethod>
get() = emptyList()
override val fields: Collection<JavaField>
get() = emptyList()
override val constructors: Collection<JavaConstructor>
get() = emptyList()
override val recordComponents: Collection<JavaRecordComponent>
get() = emptyList()
override fun hasDefaultConstructor(): Boolean = false
}
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.jvm
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.name.Name
interface SyntheticJavaPartsProvider {
@@ -16,30 +17,44 @@ interface SyntheticJavaPartsProvider {
val EMPTY = CompositeSyntheticJavaPartsProvider(emptyList())
}
context(LazyJavaResolverContext)
fun getMethodNames(thisDescriptor: ClassDescriptor): List<Name>
context(LazyJavaResolverContext)
fun generateMethods(
thisDescriptor: ClassDescriptor,
name: Name,
result: MutableCollection<SimpleFunctionDescriptor>
)
context(LazyJavaResolverContext)
fun getStaticFunctionNames(thisDescriptor: ClassDescriptor): List<Name>
context(LazyJavaResolverContext)
fun generateStaticFunctions(
thisDescriptor: ClassDescriptor,
name: Name,
result: MutableCollection<SimpleFunctionDescriptor>
)
context(LazyJavaResolverContext)
fun generateConstructors(thisDescriptor: ClassDescriptor, result: MutableList<ClassConstructorDescriptor>)
context(LazyJavaResolverContext)
fun getNestedClassNames(thisDescriptor: ClassDescriptor): List<Name>
context(LazyJavaResolverContext)
fun generateNestedClass(thisDescriptor: ClassDescriptor, name: Name, result: MutableList<ClassDescriptor>)
}
@Suppress("IncorrectFormatting") // KTIJ-22227
class CompositeSyntheticJavaPartsProvider(private val inner: List<SyntheticJavaPartsProvider>) : SyntheticJavaPartsProvider {
override fun getMethodNames(thisDescriptor: ClassDescriptor): List<Name> =
inner.flatMap { it.getMethodNames(thisDescriptor) }
context(LazyJavaResolverContext)
override fun getMethodNames(thisDescriptor: ClassDescriptor): List<Name> {
return inner.flatMap { it.getMethodNames(thisDescriptor) }
}
context(LazyJavaResolverContext)
override fun generateMethods(
thisDescriptor: ClassDescriptor,
name: Name,
@@ -48,14 +63,27 @@ class CompositeSyntheticJavaPartsProvider(private val inner: List<SyntheticJavaP
inner.forEach { it.generateMethods(thisDescriptor, name, result) }
}
context(LazyJavaResolverContext)
override fun getStaticFunctionNames(thisDescriptor: ClassDescriptor): List<Name> =
inner.flatMap { it.getStaticFunctionNames(thisDescriptor) }
context(LazyJavaResolverContext)
override fun generateStaticFunctions(thisDescriptor: ClassDescriptor, name: Name, result: MutableCollection<SimpleFunctionDescriptor>) {
inner.forEach { it.generateStaticFunctions(thisDescriptor, name, result) }
}
context(LazyJavaResolverContext)
override fun generateConstructors(thisDescriptor: ClassDescriptor, result: MutableList<ClassConstructorDescriptor>) {
inner.forEach { it.generateConstructors(thisDescriptor, result) }
}
context(LazyJavaResolverContext)
override fun getNestedClassNames(thisDescriptor: ClassDescriptor): List<Name> {
return inner.flatMap { it.getNestedClassNames(thisDescriptor) }
}
context(LazyJavaResolverContext)
override fun generateNestedClass(thisDescriptor: ClassDescriptor, name: Name, result: MutableList<ClassDescriptor>) {
inner.forEach { it.generateNestedClass(thisDescriptor, name, result) }
}
}
@@ -86,6 +86,7 @@
<configuration>
<args>
<arg>-opt-in=org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi</arg>
<arg>-Xcontext-receivers</arg>
</args>
</configuration>
</plugin>
@@ -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)