min
08/24/2026, 9:52 AMinline operator fun invoke in the companion object of an annotated classmin
08/24/2026, 9:52 AMclass MyFirExtensionRegistrar : FirExtensionRegistrar() {
override fun ExtensionRegistrarContext.configurePlugin() {
(::MyFirDeclarationGenerationExtension).unaryPlus()
}
}
class MyFirDeclarationGenerationExtension(session: FirSession)
: FirDeclarationGenerationExtension(session)
{
object Key: GeneratedDeclarationKey()
fun appliesTo(classSymbol: FirClassSymbol<*>): Boolean {
return classSymbol.hasAnnotation(
classId = ClassId.topLevel(
FqName(MyAnnotation::class.qualifiedName!!)
),
session = this.session,
)
}
override fun getNestedClassifiersNames(
classSymbol: FirClassSymbol<*>,
context: NestedClassGenerationContext,
): Set<Name> {
return when (this.appliesTo(classSymbol) && @OptIn(SymbolInternals::class) (
null == (classSymbol as? FirRegularClassSymbol)?.companionObjectSymbol
)) {
true -> setOf(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT)
else -> emptySet()
}
}
override fun generateNestedClassLikeDeclaration(
owner: FirClassSymbol<*>,
name: Name,
context: NestedClassGenerationContext,
): FirClassLikeSymbol<*>? {
return when (name.takeIf { this.appliesTo(owner) }) {
SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT ->
(FirRegularClass::symbol)(createCompanionObject(
owner = owner,
key = Key,
))
else -> null
}
}
override fun getCallableNamesForClass(
classSymbol: FirClassSymbol<*>,
context: MemberGenerationContext,
): Set<Name> {
return when (classSymbol
.takeIf { symbol -> symbol.classKind == ClassKind.OBJECT }
?.classId
?.outerClassId
?.let(this.session.symbolProvider::getClassLikeSymbolByClassId)
?.let { owner -> owner as? FirClassSymbol<*> }
?.takeIf(this::appliesTo)
?.let(::companionObject)
?.name
) {
classSymbol.classId.shortClassName -> setOf(Name.identifier("invoke"))
else -> emptySet()
}
}
}
fun companionObject(haystack: FirClassSymbol<*>): FirRegularClassSymbol? {
@OptIn(SymbolInternals::class)
return (haystack as? FirRegularClassSymbol)?.companionObjectSymbol
}
Is this the right setup?