Hello we're trying to generate the following class...
# compiler
j
Hello we're trying to generate the following class and primary constructor using k2 fir:
Copy code
// Given this 
@MyAnnotation public class Foo(public val param0: String)

// Generate the following class:
public class FooGenerated(public val param0: String)
Is it possible to do this just by implementing
generateConstructors
and using
buildPrimaryConstructor
inside of
FirDeclarationGenerationExtension
? Or would we need to instead handle part of this in IR and generate a body that assigns a constructor arg to the class field?
When trying to do this in just FIR the class is being generated, however when trying to add the val parameter to the primary constructor the following error is happening:
Copy code
Caused by: java.lang.IllegalStateException: Cannot find variable param0: R|kotlin/String| in local storage
This is the implementation of generateConstructors:
Copy code
override fun generateConstructors(context: MemberGenerationContext): List<FirConstructorSymbol> {
  val classId = context.owner.classId
  val targetConstructor = toGenerate.getValue(classId)

  return buildPrimaryConstructor {
    origin = Key.origin
    moduleData = session.moduleData
    symbol = FirConstructorSymbol(classId)  
    status = FirResolvedDeclarationStatusImpl(
      visibility = Visibilities.Public,
      modality = Modality.FINAL,
      effectiveVisibility = EffectiveVisibility.Public,
    )
    returnTypeRef = FirImplicitTypeRefImplWithoutSource
    dispatchReceiverType = FirRegularClassSymbol(classId).constructType()
      valueParameters.addAll(
        targetConstructor.valueParameterSymbols.map { param ->
          buildValueParameter {
            name = param.name
            symbol = param
            origin = Key.origin
            moduleData = session.moduleData
            returnTypeRef = param.resolvedReturnType.toFirResolvedTypeRef()
            containingFunctionSymbol = this@buildPrimaryConstructor.symbol
            isCrossinline = false
            isNoinline = false
            isVararg = false
          }
        },
      )
    }.symbol.let(::toList)
  }
}
d
1. Don't use
build...
functions to create FIR declarations, use
create...
ones (link) 2. Yes, it is possible. You need to generate constructor and then generate properties with initializer. For the initializer you need to create
FirPropertyAccessExpression
node which will point to the corresponding value parameter of the constructor. To udnerstand how to correctly generate this node I recoemmend you to inspect with debugger how the FIR for the same code written manually looks like
j
Ah thank you! Will try that and let you know if it works.
createConstructor
call worked for me thanks again for the help
👍 2