https://kotlinlang.org logo
#compiler
Title
# compiler
a

Ahmed Mourad

02/23/2024, 1:42 PM
Hallo, I have a couple of questions: 1. in fir predicates,
parentAnnotated
and
ancestorAnnotated
don't seem to return any results for me, I'm using them inside
getTopLevelClassIds
of a
FirDeclarationGenerationExtension
so supertypes should already be resolved correct? do I need to register the annotation somewhere first? 2. I need to access the resolved body of properties and functions in order to determine the classes i'm generating and their supertypes, none of the functions in the extension runs after
BODY_RESOLVE
tho? Thank you!
d

dmitriy.novozhilov

02/23/2024, 1:50 PM
1. You need to override
registerPredicates
method in your extension and register your predicates there 2. "Can" in documentation means that it is the first phase on which some method may be called, but there is no guarantee that it will be called only on this phase. Generation of declarations in FIR works in request manner: if user wrote
foo()
and your plugin said that it will generate function
foo
, then compiler will ask plugin to really generate it at the moment when it start to resolve this call (in reality it a little more complex, but the idea is that) So it all means that you can not rely on information, which is calculated on some later phase
a

Ahmed Mourad

02/23/2024, 2:17 PM
1. I do register the predicate there, if i change the predicate to
annotated
and annotate the class itself it works, but if I annotate its parent and used
parentAnnotated
it doesn't as follows:
Copy code
annotation class Marker

@Marker
interface Parent

class Child1 : Parent //isn't returned by parentAnnotated

@Marker
class Child2 //is returned by annotated
2. That's very interesting to know, thanks for the explanation! my case is that the
foo
i'm generating relies on some dsl the user is writing elsewhere, so if the user writes the following:
Copy code
class Describer : DescriptionHolder {
   override val description by describe {
      parent<SomeParent>()
      child("Child1") { .. }
      child("Child2") { .. }
  }
}
The plugin would need the info inside the
describe
block to know what classes to generate, but I can't rely on it being resolved correct? can my extension request it to be resolved at that moment?
d

dmitriy.novozhilov

02/23/2024, 3:58 PM
1. In context of predicates "parent" means not "parent superclass", but syntaxic parent
Copy code
@Marker
class Some {
    class Nested // parent is annotated with @Marker
}
Index of declarations, which can be found by predicates is created at very beggining of compilation, before any resolution So supertypes are unresolved at this stage too 2. It's not possible to generate something based on content of function bodies Assume you are adding some function to some class with plugin
Copy code
open class Base {
  protected open fun foo() {} // generated
}

class Derived : Base() {
    override fun foo() {}
}
If this class has an inheritor, then compiler may ask for generated function of this class during status resolve phase, to correctly determine the visibility of an override (in this case
Derived.foo
should be
protected
, based on
Base.foo
). And at this stage bodies are unresolved
Recently the colleague of mine wrote a very descriptive documentation of different compiler phases I recommend to check to get better understanding of how compiler works
a

Ahmed Mourad

02/26/2024, 6:44 PM
@dmitriy.novozhilov 1. I see, that makes sense! 2. Is there anything equivalent to K1's retry with additional sources? I was able to achieve this with it 🤔 Thanks for the resources! really great stuff!
d

dmitriy.novozhilov

02/27/2024, 6:38 AM
Is there anything equivalent to K1's retry with additional sources?
There isn't Originally it was made as ad-hock solution for kapt, and for K2 it was redesigned to use more cleaner approach. So now kapt and ksp are "separate tools, which call the compiler as service/library for sources analysis"
😓 1
2 Views