What is the significance of an `IrSimpleFunctionSy...
# compiler
d
What is the significance of an
IrSimpleFunctionSymbol
being bound (or not bound)? In particular, if it is being referenced so that it can be called in a generated function, is it meant to be bound to the same
IrFunction
that it represents, or to the
IrFunction
that is calling it?
r
Hi @Drew Hamilton, If I recall correctly (no sources with me), In a place like an
IrFunctionAccessExpression
which involves
IrCall
constructor calls and other expressions that represent the call site the
symbol.owner
is bound to the function being invoked. I think is unbound if you are manually constructing the call but if the call had already been resolved it should be bound to the descriptor it points to. calls to dynamic operators like
+
may be an exception in some places if I’m not mistaken.
d
Context: I am manually creating a call, and indeed the
Symbol
I resolve is unbound. This works fine in a vacuum, but when I try to use my plugin at the same time as Jetpack Compose, the Compose compiler yells at me for having an unbound symbol. I can bind to my current IrFunction, but I have no idea if that’s correct or not. Any good reading about this concept?
s
@Drew Hamilton how do you resolve the symbol? IIRC, the IrPluginContext api should always return bound one
Symbols are a way to indicate which exact function you call. Unlike bytecode calls which uses strings as descriptors, IR works on more "pointer" level, so the symbol you get should uniquely point to the function you want to use. When the symbol is bound, it means that it is connected to the function. Think about it as a function "header", which should always have some implementation behind it. The symbols must usually be bound "in the wild" apart from some weird places where IR is constructed. To resolve the symbol, you can use
IrPluginContext.reference*
, which should return you bound symbols by fqName. If those symbols are unbound, it is usually a compiler bug :)
👌 2
r
@shikasd so in this case if Drew had a
FunctionDescriptor
pointing to the resolved function in the call it would be calling
referenceFunction(resolvedDescriptor)
to get the symbol?
d
referenceSimpleFunction
, but yeah what Raul said
er, so it’s
pluginContext.symbolTable.referenceSimpleFunction
– so possibly highly relevant that i’m using the obsolete descriptor APIs?
r
I believe the plugin context may have public versions of those top level
s
Yeah, symbol table doesn't work anymore.
You should call public versions on the top level and pass fqName as a parameter
d
Not surprising 😅. For more context, I was adapting code from DataClassMembersGenerator which still uses the obsolete API. But I will try to refactor to the fqName approach, huge thanks for the pointers!
s
Good luck :) Internal compiler API can afford this, because they sometimes operate in a different phase, and have some checks around them to ensure everything is bound. Compose used to do the same (reference symbols and then force bind them), but we removed those after migrating to above-mentioned api
👍 1
You could probably see all unbound symbols with
symbolTable.allUnbound
and then ensure they are bound using
linker.getDeclaration
IIRC, but it is more like a massive hack.
👌 1
d
heh, i’ll keep that in mind if I can’t get an fqName for some reason
^ This turned out to be a simple fix and it all works as expected now. Thanks again to you both for the help!
👏 1