Would it be feasible to create a compiler plugin t...
# compiler
p
Would it be feasible to create a compiler plugin that can lift a parameter (or context-parameter) as an additional receive within the scope of a function. An example would be to have something like
Copy code
context(@Receiver _: MyScope) fun doSomething() { callSomething() }
be translated to
Copy code
context(_: MyScope) fun doSomething { with(contextOf<MyScope>()) { callSomething() } }
My gut says no but this would be a nice way of avoiding the need to create context parameter bridge functions.
y
I believe somethiing like this is possible:
Copy code
context(@Receiver _: MyScope) fun doSomething() { 
  with<MyScope>()
  callSomething()
}
Using
FirExpressionResolutionExtension
p
It looks like you found a way with
wither
@Youssef Shoaib [MOD] 😉
y
Yep! In fact, something like this is on my radar. I wanted to add receivers from pre-existing contexts so that one can have like "mega-contexts" that automatically bring in a bunch of components. Your use case is even easier. It turns out one can easily add arbitrary FIR before any resolution takes place using the status transformer extension. Hence, a plugin can simply add the
with
call based on
@Receiver
, and then wither takes care of adding it as a receiver
p
Would the plugin be able to inject the wither
with
call for any context with a specific annotated type (to avoid bridging methods) I.e.
Copy code
@ContextAsReceiver // the annotation
interface Raise { fun raise(value: Any): Nothing }

context(_: Raise) fun doSomething { raise("hello") }
y
Yeah! I think type information for parameters and such is available at that time, so you can check for annotations easily. I might whip up a prototype for you... Only gotcha is that I haven't figured out how to do the FIR transformation properly for expression bodies with inferred return type. So currently I can't make this work:
Copy code
context(_: Raise) fun doSomething() = raise("hello")
But I can make this work:
Copy code
context(_: Raise) fun doSomething(): Nothing = raise("hello")
p
I mean, for that case you'd have to specify
Nothing
explicitly, but I get what you mean 🙂
✔️ 1