jessewilson
11/20/2024, 4:47 PMclass 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:
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.
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.Youssef Shoaib [MOD]
11/20/2024, 5:15 PMFqName
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)Zac Sweers
11/20/2024, 8:05 PMFqName
or ClassId
wherever possible, or custom holder classes that implement equals() in a predictable way