Is there anything I could do to help with the gene...
# ksp
z
Is there anything I could do to help with the generated bytecode stuff? Alternatively @gavra might have some advice too as he looked into it for kapt in the past
t
You mean that subsequent compilation doesn't pick up generated classes? Sorry I had the impression that it's just some log or error message problem. Will look into it asap.
@Zac Sweers I checked out the branch: https://github.com/ZacSweers/MoshiX/tree/z/bytecode and tried
./gradlew build
but the error message is different from what you posted. I got
Copy code
> Task :moshi-ksp:tests:compileTestKotlin FAILED
e: /usr/local/google/home/laszio/working/MoshiX/moshi-ksp/tests/src/test/kotlin/dev/zacsweers/moshix/ksp/codegen/GeneratedAdaptersTest.kt: (988, 28): Unresolved reference: GeneratedAdaptersTest_MultiplePropertiesShareAdapterJsonAdapter
...
Is
./gradlew build
the right way to produce?
z
you'll want to use the more specific command (
./gradlew :moshi-ksp:tests:compileTestKotlin
), but that message is correct. Just a different manifestation of it
I'll double check to be sure
t
Oops I found out why we are seeing different messages; I used a newer version (20201120) of ksp instead of 20201110.
👍 1
OK, I arrived at the same error message now. For the not-found
UntypedNestedPersonResponse
, I cannot find the corresponding class in the build dir, though. Tried
find . -name "*UntypedNestedPersonResponse*"
in
moshi-ksp/tests
but only found
Copy code
./build/generated/ksp/src/test/resources/META-INF/proguard/moshi-dev.zacsweers.moshix.ksp.codegen.UntypedNestedPersonResponse.pro
./build/generated/ksp/src/test/kotlin/dev/zacsweers/moshix/ksp/codegen/UntypedNestedPersonResponseJsonAdapter.kt
./build/generated/ksp/classes/test/dev/zacsweers/moshix/ksp/codegen/UntypedNestedPersonResponseJsonAdapterBridge.class
maybe it is simply not generated?
z
UntypedNestedPersonResponseJsonAdapterBridge
is the correctly generated class
Copy code
UntypedNestedPersonResponseJsonAdapter.kt
is the generated kotlin file that tries to reference it
UntypedNestedPersonResponse
is not generated, it's the annotated type in source that triggers generation of the above two
t
Not sure how reliable the error message is, and not sure if I read it correctly, but
Copy code
UntypedNestedPersonResponseJsonAdapter.kt: (83, 63): Cannot access class 'dev.z
acsweers.moshix.ksp.codegen.UntypedNestedPersonResponse'. Check your module classpath for missing or conflicting dependencies
looks like that it's
UntypedNestedPersonResponse
not found, rather than
UntypedNestedPersonResponseJsonAdapterBridge
and I cannot find
UntypedNestedPersonResponse
. I think the reference to
UntypedNestedPersonResponse
comes from
UntypedNestedPersonResponseJsonAdapterBridge
so looks like that
UntypedNestedPersonResponseJsonAdapterBridge
is correctly loaded?
OK I found
UntypedNestedPersonResponse
. It's weird that it's not found.
z
I think the error message is somewhat confusing, but my perception was that it is loading the bytecode possibly correctly but the bytecode itself doesn't know how to find
UntypedNestedPersonResponse
on the same classpath
but it's odd that it says it can't access it vs a standard
NoClassDefFound
or whatever
t
In the source code
UntypedNestedPersonResponse
is generic:
Copy code
data class UntypedNestedPersonResponse<T : Personable>
However, the javap output looks suspicious:
Copy code
static dev.zacsweers.moshix.ksp.codegen.UntypedNestedPersonResponse constructorBridge(java.lang.String, int);
I tried the following
Copy code
class S {
    fun x(): Generic<Int> = TODO()
    fun y(): Generic<*> = TODO()
}
data class Generic<T: Number>(val x: Int = 0)
and javap reports
Copy code
public final class S {
    public final Generic<java.lang.Integer> x();
    public final Generic<?> y();
    ...
}
Looks like kotlinc doesn't support java raw types.
z
interesting, wouldn't it all just be erased at runtime?
t
At runtime, yes it is. At compile time, it is not type checked. I don't really know the reason but I would guess that's why kotlinc doesn't like it.
z
interesting. Is there anything we can really do about that? I'm surprised kotlinc would be checking this at all since it's already pre-compiled bytecode
t
There is probably not much we can do in ksp. The error happens when kotlinc compiles the code. On the other hand, would changing that raw type to a generic specialized with java.lang.Object feasible?
z
changing it in source or in the bytecode?
t
I mean change the return type of
constructorBridge
in
UntypedNestedPersonResponseJsonAdapterBridge
. How is it generated?
change the return type to what though? ASM only takes a JVM signature, which doesn't include generics
found some examples, will dig in further
👍 1
woof, this looks... tricky
partially because everything from KSP is kotlin types, but everything for bytecode obviously needs JVM types. I.e. things like
kotlin/String
need to be converted first
t
A lot of implementation details are hidden in kotlinc backend. It might be easier to generate kotlin code and let kotlinc deal with them, if possible. Second choice would be generating java source code although kotlin-java type conversion in this case is still needed to be taken care of.
z
in this case, generating source is not an option because we specifically want to generate bytecode to access the synthetic defaults constructor kotlinc generates
the point is that if we generate bytecode, we don't need to do reflection anymore since it will work at runtime
t
Pardon me if I forgot some of the context that you may have mentioned, but why generating calls to that synthetic default constructor doesn't work? Isn't that synthetic default constructor existed to be called by some kotlin code?
z
it can be called at runtime but synthetic elements cannot be linked against directly from source