is there a safe way to copy annotations during FIR...
# compiler
z
is there a safe way to copy annotations during FIR declaration generation from a source declaration to a generated one? I'd been just adding the original annotations to the generated declaration. That seems to work fine for simple primitives, but for
KClass
arguments it results in the parent annotation call's argumentList being unresolved (even though the class call argument within is resolved). It seems that
buildAnnotationCallCopy()
isn't enough for this case
Stranger still is that the source annotation is resolved, but even if I force it like this
Copy code
internal fun FirAnnotation.copy(newParent: FirBasedSymbol<*>): FirAnnotation {
  if (this !is FirAnnotationCall) return this
  return buildAnnotationCallCopy(this) {
    this.containingDeclarationSymbol = newParent
    this.argumentList = buildResolvedArgumentList(
      this@copy.argumentList,
      (this@copy.argumentList as FirResolvedArgumentList).mapping
    )
  }
}
It somehow becomes... unresolved? when it reaches
FirGeneratedElementsValidator.visitArgumentList()
hmm, upon further investigation, it initially passes for the annotation itself, and fails instead on the argument list to
FirGetClassCall
. I'm not exactly sure why though as the class argument here is resolved. I guess maybe we need to manually replace these during copying?
I can't find any examples of `FirGetClassCall`s that supply a resolved argument list, so I'm not sure why this validator expects it 🤔. I see a few other generators that also copy annotations like this, and presumably would have the same issue
yeah I'm kind of thinking this is a bug in GeneratedDeclarationValidation? It seems only imposed on generated declarations
if I create an anonymous
FirResolvedArgumentList
instance that just doesn't forward
acceptChildren
calls to interrupt this check, the resulting code works fine
d
It's complicated with annotation copying In general annotations on base declarations are not resolved/not fully resolved at the moment when the compiler calls the plugin. But just copying the annotations is quite a reasonable scenario, which should be supported. I've added
FirGeneratedElementsValidator
during the first implementation of the plugin API five years ago without any proper design and the whole picture of possible usecases, so ideally it should be just dropped at all until we design it properly In theory it's ok to not copy the annotations, but just reuse the same instances. So they will be resolved on the base declaration, they will be automatically resolved on the generated one too. But
FirGeneratedElementsValidator
prevents it. So you can try the following workaround: create your own inheritor of
FirAnnotationCall
, which will delegate all properties to the base annotation and has an empty
acceptChildren
implementation. I think it should work And also you need to not delegate the
sourceElement
, otherwise it could cause generation of incorrect offsets in fir2ir
z
got it. In this copy should I also replace the
containingDeclarationSymbol
to the new location?
also do you want me to file an issue for
FirGeneratedElementsValidator
?
d
In this copy should I also replace the containingDeclarationSymbol to the new location?
It worth to
also do you want me to file an issue for FirGeneratedElementsValidator?
No, we will revise it soon anyway
👍 1