Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NPE when calling returnType on method annotated if method is static and in an inner class #492

Closed
rossbacher opened this issue Jun 25, 2021 · 8 comments

Comments

@rossbacher
Copy link

rossbacher commented Jun 25, 2021

I added a test case to the play ground app that triggers that by adding a new @method annotation and running it on this code:

package com.example;

import com.example.annotation.Method;

public class JavaClass
{

  public static class Inner{

    @Method
    static String methodIn() {return "inner";}

  }
}

it works find if the annotated method is in the outer class like this:

            package com.example;

            import com.example.annotation.Method;

            public class JavaClass
            {

              @Method
              public static String methodOut(){ return "outer"; }

            }

Here is the playground app with the test cases added just run the test in the test-processor module to repro:

playground_with_bug.zip

Caused by: java.lang.NullPointerException
	at com.google.devtools.ksp.symbol.impl.java.KSClassDeclarationJavaImpl.asStarProjectedType(KSClassDeclarationJavaImpl.kt:155)
	at com.google.devtools.ksp.symbol.impl.synthetic.KSConstructorSyntheticImpl$returnType$2.invoke(KSConstructorSyntheticImpl.kt:61)
	at com.google.devtools.ksp.symbol.impl.synthetic.KSConstructorSyntheticImpl$returnType$2.invoke(KSConstructorSyntheticImpl.kt:59)
	at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at com.google.devtools.ksp.symbol.impl.synthetic.KSConstructorSyntheticImpl.getReturnType(KSConstructorSyntheticImpl.kt:59)
	at TestProcessor$TestVisitor.visitFunctionDeclaration(TestProcessor.kt:193)
	at TestProcessor$TestVisitor.visitFunctionDeclaration(TestProcessor.kt:54)
	at com.google.devtools.ksp.symbol.impl.synthetic.KSConstructorSyntheticImpl.accept(KSConstructorSyntheticImpl.kt:99)
	at TestProcessor$TestVisitor.visitClassDeclaration(TestProcessor.kt:201)
	at TestProcessor$TestVisitor.visitClassDeclaration(TestProcessor.kt:54)
	at com.google.devtools.ksp.symbol.impl.java.KSClassDeclarationJavaImpl.accept(KSClassDeclarationJavaImpl.kt:159)
	at TestProcessor$TestVisitor.visitClassDeclaration(TestProcessor.kt:201)
	at TestProcessor$TestVisitor.visitClassDeclaration(TestProcessor.kt:54)
	at com.google.devtools.ksp.symbol.impl.java.KSClassDeclarationJavaImpl.accept(KSClassDeclarationJavaImpl.kt:159)
	at TestProcessor$TestVisitor.visitFile(TestProcessor.kt:101)
	at TestProcessor$TestVisitor.visitFile(TestProcessor.kt:54)
	at com.google.devtools.ksp.symbol.impl.java.KSFileJavaImpl.accept(KSFileJavaImpl.kt:56)
	at TestProcessor.process(TestProcessor.kt:48)
	at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$4$1.invoke(KotlinSymbolProcessingExtension.kt:172)
	at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$4$1.invoke(KotlinSymbolProcessingExtension.kt:171)
	at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:249)
	at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:171)
	at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:119)
	at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:85)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:514)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:505)
	at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:112)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:505)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:189)
	... 35 more

@neetopia
Copy link
Contributor

I was not able to reproduce this in KSP's test framework. I also tried to run the playground you provided directly (disabled test), and it seems passing building, and I can also see the corresponding output in TestProcessor.log. Can you check if this has something to do with the test itself?

@neetopia
Copy link
Contributor

Corresponding log:

TestProcessor: processing JavaClass.java
com.example
PUBLIC JavaClass
com.example.JavaClass.java
class
 PUBLIC JAVA_STATIC Inner
   enclosing: com.example.JavaClass
 com.example.JavaClass.java
 class
  PUBLIC JAVA_STATIC methodIn
    annotation
      resolved to: com.example.annotation.Method
    enclosing: com.example.JavaClass.Inner
  com.example.JavaClass.java
  returnType:
    resolved to: com.example.BClass
  JAVA_STATIC methodString
    annotation
    enclosing: com.example.JavaClass.Inner
  com.example.JavaClass.java
  returnType:
    resolved to: kotlin.String
  FINAL PUBLIC <init>
    enclosing: com.example.JavaClass.Inner
  com.example.JavaClass.java
  returnType:
    resolved to: com.example.JavaClass.Inner
   resolved to: kotlin.Any
 PUBLIC JAVA_STATIC methodOut
   annotation
   enclosing: com.example.JavaClass
 com.example.JavaClass.java
 returnType:
 FINAL PUBLIC <init>
   enclosing: com.example.JavaClass
 com.example.JavaClass.java
 returnType:
   resolved to: com.example.JavaClass

@rossbacher
Copy link
Author

Hm, if you ran the tests in the attached project testInnerClassStaticMethodKotlin should fail complication with an INTERNAL_ERROR result which is caused by this crash in KSP. Are you saying that you were not able to repro that?

Let me look at the information provided.

@neetopia
Copy link
Contributor

I was able to reproduce with your test, but when I tried to isolate the issue to reproduce and add it to KSP's test framework (which is what I do when working on bugs), I was not able to reproduce with same code. Furthermore, when I just disabled test in your playground and let project build, where TestProcessor should be executing same logic as your test case (visiting the returnType and try to resolve), the build was passing, and I can see the resolved returnType for your inner class method in the printed log.

@rossbacher
Copy link
Author

I see what you are saying, I nailed it down a bit further to ((methodDeclaration as KSFunctionDeclaration).parentDeclaration as KSClassDeclaration).asStarProjectedType() being the one causing the issue in DeepLinkDispatch (which is where we are seeing this in real life) and I updated my playground test to that and now it is actually crashing in my processor code, however like you said only in the tests, it is working fine when I actually run the processor on the workload project. (Which is where it fails for us in Dee=LinkDispatch).

Still looking how to better repro it or maybe find out why it crashes in DeepLinkDispatch and the test and not in the test project.

playground_withbug2.zip

@neetopia
Copy link
Contributor

neetopia commented Jun 28, 2021

Ah I see. Bugs can also depend on the input source code in KSP, can you check if the real life workload crashing crashing in your DeepLinkDispatch processor involves some special source code scenario such as local declarations, or generics (just as examples since these historically caused some edge case bugs)?

@rossbacher
Copy link
Author

I'm still investigating but this could also be a bug in the compile testing lib then.

@rossbacher
Copy link
Author

After some more investigation I found that this must be a bug in https://github.com/tschuchortdev/kotlin-compile-testing as the non testing but we saw in DeepLinkDispatch was just a side effect of another issue and not related to this.

Found tschuchortdev/kotlin-compile-testing#105 which is describing our issue. Closing this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants