https://kotlinlang.org logo
Title
e

elihart

10/27/2021, 2:26 AM
I’m running into a pretty tricky XProcessing/KSP crash, and trying to figure out what the root cause is.
Caused by: java.lang.IllegalArgumentException: EpoxyModel<*> is not a sub type of the class/interface that contains `equals` (EpoxyModel)
        at com.google.devtools.ksp.processing.impl.ResolverImpl.computeAsMemberOf(ResolverImpl.kt:972)
        at com.google.devtools.ksp.processing.impl.ResolverImpl.asMemberOf$compiler_plugin(ResolverImpl.kt:954)
        at com.google.devtools.ksp.symbol.impl.java.KSFunctionDeclarationJavaImpl.asMemberOf(KSFunctionDeclarationJavaImpl.kt:124)
        at androidx.room.compiler.processing.ksp.KSAsMemberOfKt.typeAsMemberOf(KSAsMemberOf.kt:67)
        at androidx.room.compiler.processing.ksp.KspExecutableParameterElement$type$2.invoke(KspExecutableParameterElement.kt:44)
        at androidx.room.compiler.processing.ksp.KspExecutableParameterElement$type$2.invoke(KspExecutableParameterElement.kt:43)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at androidx.room.compiler.processing.ksp.KspExecutableParameterElement.getType(KspExecutableParameterElement.kt:43)
        at androidx.room.compiler.processing.ksp.KspExecutableParameterElement.getType(KspExecutableParameterElement.kt:26)
This happens when I access a certain`XVariableElement.type` , which is a parameter of a function inside my EpoxyModel<T> class. There seems to be a bug with how the generics are handled, but I can’t tell if it is something XProcessing is doing wrong or KSP itself. What is strange is that when
ResolverImpl.computeAsMemberOf
fails the check for
containing.kotlinType.isSubtypeOf(functionDeclaredIn)
it doesn’t consider
EpoxyModel<*>
as a subclass of
EpoxyModel
. I have tried to reproduce this in a unit test, and can’t so far, because other cases like
ArrayList<*>
vs
ArrayList
work fine. Digging deeper into it, the
isSubtypeOf
function ends up comparing two
LazyJavaClassDescriptor
instances representing the same class, but that type doesn’t seem to implement “equals” so because they are different instances the check fails.
Here’s a screenshot of the debugger where you can see that the super classifier
it
seems like it should match the
classDeclaration
, but the
==
still fails
y

yigit

10/27/2021, 2:28 AM
by any chance, did you capture them in different rounds?
e

elihart

10/27/2021, 2:28 AM
that could be… let me check that
yeah, this is happening in
finish
when the types were saved in a list from the previous round. wow, that must be it. Thanks @yigit for identifying in a few seconds what I’ve been banging my head on for a few hours 😭 ouch
y

yigit

10/27/2021, 2:33 AM
well a fresh look is always advantegous. btw , danny did something to find these elements back again between rounds, in case they are deferred events. snapshot of xprocessing should be handling that
e

elihart

10/27/2021, 2:35 AM
super helpful, thanks!
j

Jiaxiang

10/27/2021, 6:13 AM
all information including KS symbols should be discarded in different rounds, were you keeping a global list to store the types across rounds?
e

elihart

10/27/2021, 4:36 PM
I had stored some data classes representing my generated files and waited until “finish” to run some validations on them (to make a best effort at generating files before emitting errors, since otherwise code depends on the generated classes and compilation is a mess).
its easy enough to do another way now that I know the problem 😅