[FE 1.0] Allow generation of nested classes for java classes from plugins
This commit is contained in:
+3
-1
@@ -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",
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+41
-22
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -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>) {
|
||||
|
||||
+202
@@ -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
|
||||
}
|
||||
}
|
||||
+30
-2
@@ -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>
|
||||
|
||||
+24
-1
@@ -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) }
|
||||
|
||||
+3
@@ -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
|
||||
|
||||
+11
-3
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user