I’ve got an <IR plugin> that operates on code like...
# compiler
j
I’ve got an IR plugin that operates on code like this:
Copy code
class MyTest(
  private val roshambo: Roshambo = Roshambo.ROCK,
) {

  enum class Roshambo(val gesture: String) {
    ROCK("fist"),
    SCISSORS("peace"),
    PAPER("flat"),
  }
}
I want to match the default parameter value to its enum declaration. I’ve implemented this by extracting the symbols on each and doing an
equals()
comparison. It ends up doing something like this:
Copy code
val parameterEnumSymbol: IrEnumEntrySymbol =
    (parameter.defaultValue!!.expression as IrGetEnumValue).symbol

  val enumClass = pluginContext.referenceClass(parameter.type.getClass()!!.classId!!)!!.owner
  val enumEntries = enumClass.declarations.filterIsInstance<IrEnumEntry>()
  val declaredEnumSymbol: IrEnumEntrySymbol = enumEntries[0].symbol

  val match = parameterEnumSymbol == declaredEnumSymbol
This works... most of the time. But in one instance I’ve seen, the two symbols are different objects and are not equal to each other.
Copy code
parameterEnumSymbol = {IrEnumEntrySymbolImpl@13988} ENUM_ENTRY name:ROCK
declaredEnumSymbol = {IrEnumEntrySymbolImpl@19381} ENUM_ENTRY name:ROCK
match = false
(They also have different instances for the
IrEnumEntryImpl owner
.) Is it a bug to compare symbols of the same type with
==
? Is there a best practice for comparing symbols? I can attempt to get a canonical instance by looking it up in
PluginContext
, or I could get an
FqName
for the symbol and compare those.
y
FqName is probably your best best if I had to guess. Uniqueness of
FqName
seems to be a central assumption to how the compiler works, even when sometimes that isn't fulfilled (e.g. one can redefine kotlin's internal annotations and thus be able to use them in their own code)
thank you color 1
z
yeah we use
FqName
or
ClassId
wherever possible, or custom holder classes that implement equals() in a predictable way