google / ksp

Kotlin Symbol Processing API
https://github.com/google/ksp
Apache License 2.0
2.89k stars 274 forks source link

[KSP2] asMemberOf() throws exception with a generic type without arguments #1725

Closed kuanyingchou closed 9 months ago

kuanyingchou commented 9 months ago

This may be intended behavior and I haven't figured out why we do this in XProcessing but calling asMemberOf() with a generic type without supplying arguments like this:

functionDeclaration.asMemberOf(classDeclaration.asType(emptyList()))

leads to exceptions like this in KSP2 but not in KSP1:

' expects '2' type arguments but type 'Base' has 0 type arguments.
    at org.jetbrains.kotlin.analysis.api.fir.components.KtFirTypeProvider.getSubstitutedSuperTypes(KtFirTypeProvider.kt:283)
    at org.jetbrains.kotlin.analysis.api.fir.components.KtFirTypeProvider.getDirectSuperTypes(KtFirTypeProvider.kt:263)
    at org.jetbrains.kotlin.analysis.api.fir.components.KtFirTypeProvider.getDirectSuperTypes(KtFirTypeProvider.kt:251)
    at org.jetbrains.kotlin.analysis.api.components.KtTypeProviderMixIn.getDirectSuperTypes(KtTypeProvider.kt:141)
    at org.jetbrains.kotlin.analysis.api.components.KtTypeProviderMixIn.getDirectSuperTypes$default(KtTypeProvider.kt:140)
    at com.google.devtools.ksp.impl.IncrementalContextAA.recordLookupWithSupertypes$lambda$13$record(IncrementalContextAA.kt:221)
    at com.google.devtools.ksp.impl.IncrementalContextAA.access$recordLookupWithSupertypes$lambda$13$record(IncrementalContextAA.kt:67)
    at com.google.devtools.ksp.impl.IncrementalContextAA.recordLookupWithSupertypes(IncrementalContextAA.kt:231)
    at com.google.devtools.ksp.impl.IncrementalContextAAKt.recordLookupWithSupertypes(IncrementalContextAA.kt:240)
    at com.google.devtools.ksp.impl.IncrementalContextAAKt.recordLookupWithSupertypes$default(IncrementalContextAA.kt:239)
    at com.google.devtools.ksp.impl.ResolverAAImpl.computeAsMemberOf$kotlin_analysis_api(ResolverAAImpl.kt:720)
    at com.google.devtools.ksp.impl.symbol.kotlin.KSFunctionDeclarationImpl.asMemberOf(KSFunctionDeclarationImpl.kt:114)
    at com.google.devtools.ksp.processor.AsMemberOfProcessor.process(AsMemberOfProcessor.kt:22)
    at com.google.devtools.ksp.impl.KotlinSymbolProcessing.execute(KotlinSymbolProcessing.kt:528)
    at com.google.devtools.ksp.test.AbstractKSPAATest.runTest(AbstractKSPAATest.kt:141)
    at com.google.devtools.ksp.test.AbstractKSPTest.runTest(AbstractKSPTest.kt:227)
    at com.google.devtools.ksp.test.KSPAATest.testAsMemberOf(KSPAATest.kt:130)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.invokeAll(ForkJoinPoolHierarchicalTestExecutorService.java:129)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService.invokeAll(ForkJoinPoolHierarchicalTestExecutorService.java:129)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.ForkJoinPoolHierarchicalTestExecutorService$ExclusiveTask.compute(ForkJoinPoolHierarchicalTestExecutorService.java:185)
    at java.base/java.util.concurrent.RecursiveAction.exec(RecursiveAction.java:189)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
    at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)

Tested with https://github.com/google/ksp/commit/42217b8cbf11609d42eee71a607e4011904c6cd8 and 2.0.0-Beta3-1.0.18-20240207.110119-15.

neetopia commented 9 months ago

I can't seem to reproduce this issue in our test setup, can you provide more context on the classes involved in this test?

kuanyingchou commented 9 months ago

Oh, I used AsMemberOfProcessor and this:

val base = resolver.getClassDeclarationByName("Base")!!
val function = base.getDeclaredFunctions().single { it.simpleName.asString() == "returnArg1" }
function.asMemberOf(base.asType(emptyList()))

Base is defined in asMemberOf.kt:

open class Base<BaseTypeArg1, BaseTypeArg2> { ... }