Hi, i am writing a compiler plugin. I have diffic...
# compiler
j
Hi, i am writing a compiler plugin. I have difficulties calling a method on an object (property of a class). For example, with static methods I do it with `pluginContext.referenceFunctions(FqName("kotlin.io.println")); irCall(funPrintln) ...``. Can anyone give me a tip on how this works with functions on an instance? Thanks!
s
You need to find a class first, then find the required function inside to get the symbol/fn instance. To call, you just do
irCall
and put
dispatchReceiver
property to point to instance. (similar for extension functions, just use
extensionReceiver
there)
It might be the case that you don't have to find the class btw, but I am not sure
referenceFunctions
works this way
r
To add to Andrei's comments if you need to get the receiver expression, if the instance is an object you may have to get a hold of it with something like
IrGetObjectValueImpl
If it's a class and you need to contruct an instance first
IrConstructorCallImpl
j
Thank you. I think I am getting somewhere! I think the last piece I am missing how to retrieve the instance. That's my code
Copy code
override fun lower(irClass: IrClass) {
  val propertyToClose: IrProperty = /* ... */

  val propertyClassSymbol: IrClassSymbol = pluginContext.findClassOf(propertyToClose)
  val propertyClass: IrClass = propertyClassSymbol.owner
  val propertyCloseFunction: IrSimpleFunction = propertyClass.functions.single { it.name == closeName }
  closeFunction.body = DeclarationIrBuilder(pluginContext, closeFunction.symbol).irBlockBody {
    +irCall(propertyCloseFunction).apply {
      dispatchReceiver = irGetField(irClass.thisReceiver /* Type mismatch: IrValueParameter vs IrExpression? */, propertyToClose.backingField!!)
  }
}
How do I get the instance of the property?
n
I think you should add
irGet
around irClass.thisReceiver
j
Hm. This compiles, but during code generation I'm getting a
No mapping for symbol: VALUE_PARAMETER INSTANCE_RECEIVER
. This is the `dump()`of the generated IR:
Copy code
CALL 'public open fun close (): kotlin.Unit declared in <root>.ExternalResource' type=kotlin.Unit origin=null
      $this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:firstResource type:<root>.ExternalResource visibility:private [final]' type=<root>.ExternalResource origin=null
        receiver: GET_VAR '<this>: <root>.ResourceManager declared in <root>.ResourceManager' type=<root>.ResourceManager origin=null
This is what i ant to generate:
Copy code
CALL 'public open fun close (): kotlin.Unit declared in <root>.ExternalResource' type=kotlin.Unit origin=null
            $this: CALL 'private final fun <get-firstResource> (): <root>.ExternalResource declared in <root>.ResourceManager' type=<root>.ExternalResource origin=GET_PROPERTY
              $this: GET_VAR '<this>: <root>.ResourceManager declared in <root>.ResourceManager.close' type=<root>.ResourceManager origin=null
n
You can try getting ResourceManager instance from the function, like
closeFunction.dispatchReceiverParameter
IIRC. Assuming closeFunction is a member of the manager
j
It works now: Instead of
irGet(irClass.thisReceiver!!)
it works with
irGet(thisCloseFunction.dispatchReceiverParameter!!)
Full snippet:
Copy code
override fun lower(irClass: IrClass) {
    /* ... */
    val propertyToClose: IrProperty = /* ... */
    val propertyClassSymbol: IrClassSymbol = pluginContext.findClassOf(propertyToClose)
    val propertyClass: IrClass = propertyClassSymbol.owner
    val propertyCloseFunction: IrSimpleFunction =
      propertyClass.functions.single { it.name == closeName }

    thisCloseFunction.body = DeclarationIrBuilder(pluginContext, thisCloseFunction.symbol).irBlockBody {
      +irCall(propertyCloseFunction).apply {
        dispatchReceiver = irCall(propertyToClose.getter!!).apply {
          dispatchReceiver = irGet(thisCloseFunction.dispatchReceiverParameter!!)
        }
      }
    }
  }
Thanks for the help and nudges in the right direction 🙂
BTW: My proof of concept of "imitating" RAII of C++ is finished. Would love to get some feedback. https://github.com/jbarop/kraii/
161 Views