Jacob Applin
02/03/2025, 6:25 PMgetstatic
which results in this exception at runtime Expected static field foo.SampleClass.param0
.Jacob Applin
02/03/2025, 6:26 PMoverride fun getCallableNamesForClass(
classSymbol: FirClassSymbol<*>,
context: MemberGenerationContext
): Set<Name> {
return setOf(Name.identifier("sample"))
}
override fun generateFunctions(
callableId: CallableId,
context: MemberGenerationContext?
): List<FirNamedFunctionSymbol> {
return createMemberFunction(
owner = context!!.owner,
key = Key,
name = callableId.callableName,
returnType = context.owner.constructType()
).symbol.let(::listOf)
}
Ir implementation:
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
val parentClass = declaration.parentAsClass
val builder = IrBlockBodyBuilder(
context = context,
scope = Scope(declaration.symbol),
startOffset = -1,
endOffset = -1,
)
builder.run {
declaration.body = context.irFactory.createBlockBody(-1, -1) {
statements += irReturn(
irCallConstructor(
callee = parentClass.primaryConstructor!!.symbol,
typeArguments = emptyList(),
).apply {
parentClass.properties.forEachIndexed { index, property ->
putValueArgument(index, irCall(property.getter!!))
}
},
)
}
}
}
Jacob Applin
02/03/2025, 6:27 PMCompiled from "Source0.kt"
public final class foo.SampleClass {
public foo.SampleClass(java.lang.String);
Code:
0: aload_1
1: ldc #10 // String param0
3: invokestatic #16 // Method kotlin/jvm/internal/Intrinsics.checkNotNullParameter:(Ljava/lang/Object;Ljava/lang/String;)V
6: aload_0
7: invokespecial #19 // Method java/lang/Object."<init>":()V
10: aload_0
11: aload_1
12: putfield #22 // Field param0:Ljava/lang/String;
15: return
public final foo.SampleClass sample();
Code:
0: new #2 // class foo/SampleClass
3: dup
4: getstatic #22 // Field param0:Ljava/lang/String;
7: invokespecial #28 // Method "<init>":(Ljava/lang/String;)V
10: areturn
}
bnorm
02/03/2025, 6:37 PMirCall
, otherwise it won't be treated as member access.
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
val receiver = declaration.dispatchReceiverParameter ?: return
val parentClass = declaration.parentAsClass
val builder = DeclarationIrBuilder(context, declaration.symbol)
declaration.body = builder.irBlockBody {
+irReturn(
irCallConstructor(
callee = parentClass.primaryConstructor!!.symbol,
typeArguments = emptyList(),
).apply {
parentClass.properties.forEachIndexed { index, property ->
putValueArgument(index, irCall(property.getter!!).apply {
dispatchReceiver = irGet(receiver)
})
}
},
)
}
}
Jacob Applin
02/03/2025, 6:40 PMJacob Applin
02/03/2025, 6:40 PMparentClass.properties.forEachIndexed { index, property ->
putValueArgument(index, irCallOp(
callee = property.getter!!.symbol,
type = property.getter!!.returnType,
dispatchReceiver = irGet(declaration.dispatchReceiverParameter!!),
))
}
Jacob Applin
02/03/2025, 6:42 PMparentClass.thisReceiver
and irGetField
etc