Hi, I'm trying to build a compiler plugin, and am ...
# compiler
u
Hi, I'm trying to build a compiler plugin, and am working my way throught the AST, I have a
KtNamedFunction
. Is there a way to check if the type it represents, is a subclass of some another type? Or is that simply too soon to say at that point?
y
What extension are you using? If you're in an
AnalysisHanflerExtension.analysisCompleted
then you can use the
BindingContext.getType(KtElement)
to get a
KotlinType
that you can call
isSubtypeOf
on
u
To be honest I'm not sure. I'm working on Anvil custom code generator, which just gives me callback of
Copy code
override fun generateCode(
        codeGenDir: File,
        module: ModuleDescriptor,
        projectFiles: Collection<KtFile>
    ): Collection<GeneratedFile> {
so I traverte the KtFiles as needed and I generate code there
It's probably none of there, right?
y
Using an Anvil plugin probably won't help you out too much here I don't think. Instead, make a normal Kotlin compiler plugin like this template
u
Why do you think so? They exposed their codegen infrastructure for quick custom codegens related to DI, it works fine. I just wanted to add extra check on the annotated type (see its supertypes) https://github.com/square/anvil/blob/main/compiler-api/README.md
Copy code
interface Bar
class Foo : Bar

@MyAnnotation fun foo() : Foo = Foo()
Copy code
@MyAnnototation = validate Foo extends Bar, else fail build
y
The issue is that they don't expose the
BindingContext
which includes all the analysis information about types, functions, etc. Without it, you can't realistically determine whether a type extends another or not
u
I see, bummer
ill open issue with them, thank you!
If I may OT, while you're here. How would I find a annotation of a annotation? I list all annotations of the function via
annotatedEntries
, and now how would I match one that has
@Scope
?
Copy code
@Scope <------
@Retention(AnnotationRetention.RUNTIME)
annotation class AppScope
r
Hi @ursus. if you want to know when an annotation is annotated it may be something like:
Copy code
fun AnnotationDescriptor.containsMetaAnnotation(name: FqName): Boolean =
  type.constructor.declarationDescriptor?.annotations?.hasAnnotation(name) == true
appScopeEntry.containsMetaAnnotation(FqName("your.package.Scope"))
u
I'm sorry but how would I get AnnotationDescriptior from
KtAnnotationEntry
? I have
KtNamedFunction.annotationEntries : List<KtAnnotationEntry>
I'm trying `
Copy code
it.annotationEntries.first().typeReference?.annotations
but its empty even though there are meta annotations
r
that code I shared is for the descriptor api. To get the descriptors for
KtAnnotationEntry
or the type, you need as Youssef mentioned before, the BindingContext
AFAIK To resolve an annotation of an annotation you need the descriptor or walk the tree yourself and match on the strings you find. KtElement has no type or fqNames associated until descriptors are paired to them in the trace binding context during analysis.
u
hm okay I might be out of my depth. What I tried to do with that sample makes no sense? get applied annotations of my function, get each one's type and check its applied annots.
r
it makes sense, it’s the same we do in arrow meta in the proofs plugin where any annotation can be annotated with
@Context
but not sure you can build that on top of Anvil without access to the BindingContext. You would need your own plugin that has access to the BindingContext in analysisCompleted, call checker or declaration chequer extension points and with that you can resolve calls, declarations and annotations.