Skip to content

test: cover annotation lookup when class values cannot be loaded - #3108

Open
mvanhorn wants to merge 4 commits into
google:mainfrom
mvanhorn:test/1038-annotation-arbitrary-class-value-coverage
Open

test: cover annotation lookup when class values cannot be loaded#3108
mvanhorn wants to merge 4 commits into
google:mainfrom
mvanhorn:test/1038-annotation-arbitrary-class-value-coverage

Conversation

@mvanhorn

@mvanhorn mvanhorn commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Split out from #3092 at @jaschdoc's request, so the test lands before any behaviour change.

Tests only. No production code is touched, and the EXPECTED block records what KSP does today, so a later behaviour change shows up as a diff in this file rather than as new coverage arriving alongside the change.

The existing annotationWithArbitraryClassValue test covers reading the annotation through getAnnotationsByType, where touching a KClass value throws KSTypeNotPresentException because the referenced class is not on the processor's classpath. This adds the two things around it that were untested:

  • isAnnotationPresent on that same annotation. The class values still cannot be loaded, so this pins down whether presence is answerable without loading them.
  • A second annotation, nested in a private object, that shares the simple name ClassValueAnnotation but not the qualified name. Both getAnnotationsByType(...).count() and isAnnotationPresent(...) are asserted against it, which pins the lookup to qualified-name matching rather than simple-name matching.

Current behaviour, now recorded in EXPECTED:

User
String, Company, IntArray, Array<User>
true
0
false

Verified with:

./gradlew :kotlin-analysis-api:test --tests "*ConfiguredUnitTestSuite.testAnnotationWithArbitraryClassValue*"

Both AAConfiguredUnitTestSuite and PsiConfiguredUnitTestSuite pass on unmodified upstream code.

Related: #1038

Adds coverage to the existing AnnotationArbitraryClassValueProcessor test for
the current behaviour of isAnnotationPresent and getAnnotationsByType on an
annotation whose KClass values are not loadable by the processor classloader.

Also covers a second annotation that shares the simple name but not the
qualified name, which pins the lookup to qualified-name matching.

No production code changes; the EXPECTED block records what KSP does today so
a later behaviour change shows up as a diff here.
@jaschdoc

jaschdoc commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Hi thanks for the PR. Could you please create an entirely new test and register it in KSPUnitTestSuite along with the appropriate values for the @Bug annotation (again, see the contributing docs)? Doing so makes it easier to see what the test does and to isolate the test behavior.

@jaschdoc jaschdoc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per review, isolate the behavior instead of folding it into
annotationWithArbitraryClassValue. Add isAnnotationPresentWithArbitraryClassValue
with its own processor and testData, registered in KSPUnitTestSuite with
@bug(issues/1038, OPEN) and @TestMetaData, and drop those assertions from the
original test.
@mvanhorn

mvanhorn commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Done. isAnnotationPresentWithArbitraryClassValue is now its own test with its own processor and testData, registered in KSPUnitTestSuite with @Bug("https://github.com/google/ksp/issues/1038", BugState.OPEN) and @TestMetadata.

Those assertions are out of annotationWithArbitraryClassValue, so that test and its processor are back to their original form. That is why the diff now touches only the three new/changed files.

Both suites pass locally: AAConfiguredUnitTestSuite and PsiConfiguredUnitTestSuite, new test and the restored original.

@jaschdoc jaschdoc left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please clarify how this reproduces the bug in #1038? I would expect the test to fail or throw an error, in which case the test should be green with runFailingTest or runThrowingTest, respectively.

The test now asserts KSTypeNotPresentException is thrown when accessing
the arbitrary class value, and the processor exercises the failing
.value.qualifiedName access directly.
@mvanhorn

mvanhorn commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Good push, the test as written did not demonstrate the failure. It now runs through runThrowingTest expecting KSTypeNotPresentException, and the processor accesses .value.qualifiedName directly, which is the exact access that blows up in #1038. So the suite documents today's throwing behavior, and when a fix lands the test flips to asserting the resolved qualified name.

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

Successfully merging this pull request may close these issues.

2 participants