google / ksp

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

nested java class resolves to error with kotlin compile testing 1.3.5 #263

Open yigit opened 3 years ago

yigit commented 3 years ago

I couldn't yet reproduce this in KSP so might not be a KSP issue but after updating room to use kotlin compile testing 1.3.5 (where there was a bug fix to pass down java files as root files), a room test started failing:

Test input:

            import java.util.List;
            class Baz {
                int intField;
                List<Integer> listOfInts;
                List incompleteGeneric;
                Nested nested;
                static class Nested {
                }
            }

Resolving the nested field's type returns error.

override fun resolve(): KSType {
        val resolvedType = ResolverImpl.instance.resolveUserType(this)
        return if ((resolvedType.declaration as? KSClassDeclarationDescriptorImpl)?.descriptor is NotFoundClasses.MockClassDescriptor) {
            KSErrorType
        } else resolvedType
    }

Another change was to update kotlin to 1.4.21-2, that might also be related. Will investigate further.

yigit commented 3 years ago

can reproduce w/ kotlin compile testing w/o room. still investigating. https://github.com/yigit/kotlin-compile-testing/commit/2e35c09fa1bc26186cfbfbc5238ba2f7000af5f3

yigit commented 3 years ago

and it works fine if i don't add it as a java source roots:

https://github.com/google/ksp/blob/master/compiler-plugin/src/main/kotlin/com/google/devtools/ksp/KotlinSymbolProcessingPlugin.kt#L200

maybe our testing infra does not do that?

yigit commented 3 years ago

in kotlin compile testing, resolvedType.declaration is KSClassDeclarationDescriptorImpl while in KSP test infra, it is KSClassDeclarationJavaImpl.

yigit commented 3 years ago

moved to kotlin compile testing as i cannot reproduce this in a sample project. https://github.com/tschuchortdev/kotlin-compile-testing/issues/105

yigit commented 3 years ago

i can reproduce this little bit easier by finding the nested class directly and calling asStarType because it fails with NPE in:

private val descriptor: ClassDescriptor? by lazy {
        ResolverImpl.moduleClassResolver.resolveClass(JavaClassImpl(psi))
    }

but again, works fine in ksp testing infra, fails in kotlin compile testing.

yigit commented 3 years ago

i have some level of repro for this: https://github.com/yigit/ksp/commit/8b15edb6a779829986ba065e8860aab540c9edd1

still trying to isolate and not sure why i couldn't repro in my test. similarly it happens in a java source class but it is actually a root class, not a nested one.

yigit commented 3 years ago

to keep the bug updated, it happens in KSP test infra when the file path does not match the class's package name.

This is something IDE complains about in a regular project but nevertheless, javac compiles it w/o any issues (and kotlin compiler is fine w/ that too).

I'm still not sure how/why we create the PSI file triggers this, not i'm not sure how to find the correct source root for kotlin compile testing.

yigit commented 3 years ago

so tl;dr; I created a sample project where i have:

package foo.bar;
class JavaSrc {
}
package foo.baz;
class KotlinSrc {
}

This code compiles fine. But if I change KotlinSrc class to reference JavaSrc, compilation fails.

Seems like the tl;dr; is that this is OK for java but not ok from kotlin. Moreover, if I move that JavaSrc to a dependent module, it again works fine from kotlin (because it is a class file).

ting-yuan commented 3 years ago

Per offline discussion, the behavior is aligned to kotlinc when used through kotlin-gradle-plugin. Investigations are needed when calling directly.