:wave: I have the following situation: Given ```@...
# compiler
j
👋 I have the following situation: Given
Copy code
@ContributesBinding(AppScope::class)
@ContributesBinding(AltScope::class)
@Inject
class ContributingClass : SomeInterface
I generate some nested classes in a
FirDeclarationGenerationExtension
where we end up with
Copy code
@ContributesBinding(AppScope::class)
@ContributesBinding(AltScope::class)
@Inject
class ContributingClass : SomeInterface {

  @Contribution(AppScope::class)
  class NestedContribution

  @Contribution(AltScope::class)
  class NestedContribution2
}
After ``FirDeclarationGenerationExtension#generateNestedClassLikeDeclaration` has run and generated both classes, we get to
FirSupertypeGenerationExtension#computeAdditionalSupertypes
and I try to query for the nested classes but I'm not able to find them. Things I've tried include •
session.predicateBasedProvider.getSymbolsByPredicate(parentAnnotated(contributesBinding))
- this finds `ContributingClass`'s constructor •
session.predicateBasedProvider.getSymbolsByPredicate(annotated(contribution))
- this finds nothing • Accessing `ContributingClass`'s
declarationSymbols
-- this finds the constructor Is it possible to access the nested generated classes here? Based on some older discussions I was thinking this should be possible so I'm not sure if perhaps I'm setting something up incorrectly, or that the generated nested classes are just not accessible yet at this phase. Additional notes: • I have all the predicates registered in the
FirSupertypeGenerationExtension
• Right now this is for all code living in the same module/compilation
d
Only source-declared declarations might be found by predicates. Generated ones are not added to indices even if they match some predicate. There are two ways to access generated declarations: • store them in some custom caches which is shared between different extensions of your plugin • search for them with scopes. All non top-level declarations are added into special scope which is part of the declared scope of the outer class. So you can do just this:
Copy code
val declaredScope = (classLikeDeclaration as? FirClass)
    ?.symbol
    ?.declaredMemberScope(session, memberRequiredPhase = null)
    ?: FirTypeScope.Empty

val nestedClass = declaredScope.getSingleClassifier(Name.identifier("NestedContribution"))
Note that declared scope is accessible anytime, but use-site scope (it looks for declarations not only in the class itself, but in its supertypes too) is available only after the supertype generation phase. Also use lookups in scopes carefully if you do that inside the `FirDeclarationGenerationExtension`: scope calls the extension under the hood, so if you try to access the same scope from the extension you can fall into infinite recursion
j
Got it, this is perfect! Thanks for the thorough explanation