square / moshi

A modern JSON library for Kotlin and Java.
https://square.github.io/moshi/1.x/
Apache License 2.0
9.78k stars 761 forks source link

Improve error messaging on Unit/Nothing/Void types in code gen #1084

Open lassem opened 4 years ago

lassem commented 4 years ago

I am unable to pinpoint the exact reason why this happens, could really use some help in tracking this down.

(fwiw, 1.10.0-SNAPSHOT also has this issue)

Stacktrace from the build:

e: [kapt] An exception occurred: java.lang.IllegalStateException: Parameter with void, Unit, or Nothing type is illegal
        at com.squareup.moshi.kotlin.codegen.api.KotlintypesKt.asTypeBlock(kotlintypes.kt:92)
        at com.squareup.moshi.kotlin.codegen.api.AdapterGenerator.generateFromJsonFun(AdapterGenerator.kt:417)
        at com.squareup.moshi.kotlin.codegen.api.AdapterGenerator.generateType(AdapterGenerator.kt:249)
        at com.squareup.moshi.kotlin.codegen.api.AdapterGenerator.prepare(AdapterGenerator.kt:151)
        at com.squareup.moshi.kotlin.codegen.JsonClassCodegenProcessor.process(JsonClassCodegenProcessor.kt:117)
        at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt)
        at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:147)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:802)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:713)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1043)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1184)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1068)
        at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:79)
        at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:35)
        at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.runAnnotationProcessing(Kapt3Extension.kt:224)
        at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:187)
        at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:98)
        at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM$analyzeFilesWithJavaIntegration$2.invoke(TopDownAnalyzerFacadeForJVM.kt:97)
        at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:107)
        at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:82)
        at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:557)
        at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:82)
        at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:107)
        at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:548)
        at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:177)
        at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:165)
        at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:55)
        at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:84)
        at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:42)
        at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:104)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1558)
        at sun.reflect.GeneratedMethodAccessor101.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
        at sun.rmi.transport.Transport$1.run(Transport.java:200)
        at sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:573)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:834)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:688)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:687)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)
ZacSweers commented 4 years ago

Do you have a reproducing sample code snippet? Unfortunately not really actionable without one. If you can’t pinpoint one and the project is private, you can clone moshi locally, open it in an IDE, enable remote debugging on your project build, and then connect a remote debugger from the moshi IDE. If you set a breakpoint on that like you should be able to backtrack and see what class from your project it’s trying to process, then you can share that (or similar) as a repro case.

ZacSweers commented 4 years ago

In the mean time we can try to add more information to the error message (such as the original property it’s analyzing). If I made a PR with such a change, would you be able to try that locally or an updated snapshot?

lassem commented 4 years ago

Absolutely!

lassem commented 4 years ago

We had an object defined like this:

@JsonClass(generateAdapter = true)
data class ScheduleInvoiceResponse(
    val responseInfo: ResponseInfo?,
    val result: Unit?
)

Wasn't immediately obvious where this problem lied, so some improvements to the actual error message would be nice.

ZacSweers commented 4 years ago

That seems obvious, right?

Parameter with void, Unit, or Nothing type is illegal

Do you have a custom adapter for Unit that can somehow fulfill that model? I’m curious what the use case is vs making it Any?

ZacSweers commented 4 years ago

We can try to make this error on the specific element though to make it more clear :+1:

lassem commented 4 years ago

We're trying to figure out exactly that. I changed it to Any? as Unit? didn't make much sense. And no, no custom adapter in this case.

result wasn't even used.