Read @UseCase through UAST so Kotlin tests are supported - #1
Open
atrifyllis wants to merge 1 commit into
Open
atrifyllis wants to merge 1 commit into
atrifyllis wants to merge 1 commit into
Conversation
The four code-side extensions read annotations through the Java PSI model, so a @usecase on a Kotlin test method is invisible to all of them: no gutter icon, no inspection, no Find Usages, and no spec-to-test navigation landing in real source. Switch them to UAST, the platform's language-neutral view of JVM annotations, and register the line marker and the inspection for the UAST meta-language instead of JAVA. One code path now serves Java, Kotlin and any other language with a UAST implementation, with no new runtime dependency: the Kotlin plugin is added to the build only so the tests have a Kotlin language to parse. The annotation type itself may now be declared in Kotlin as well - it is still looked up by short name through PsiShortNamesCache, which sees light classes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In a project whose tests are written in Kotlin, none of the code-side features fire: no gutter icon on
@UseCase, no "ID has no matching spec" inspection, and no Find Usages in either direction. The Markdown side and the diagram tool window work, so the plugin looks half-installed rather than broken, which is what sent me reading the source.The cause is that all four code-side extensions speak Java PSI —
PsiAnnotation,PsiLiteralExpression,AbstractBaseJavaLocalInspectionTool— andplugin.xmlregisters the line marker and the inspection forlanguage="JAVA".What this changes
The four extensions now read annotations through UAST, the platform's language-neutral view of JVM annotations, and the two registrations move from
language="JAVA"tolanguage="UAST". One code path then serves Java, Kotlin and anything else with a UAST implementation.UseCaseToSpecLineMarkerProvider,UseCaseIdInspection,UseCaseDeclarationProvider,UseCaseUsageSearcher—UAnnotationin place ofPsiAnnotation, values read viaevaluate()and anchored onsourcePsi.UseCaseIndexgains the shared helpers (isUseCaseAnnotation,attributeString,attributeStrings,arrayElements) and keeps its Java-array handling; the array unwrapper covers Java's{...}and Kotlin's[...].build.gradle.ktsonly so the tests have a Kotlin language to parse andrunIdea sandbox to try it in.UseCaseIndex's lookups needed no change:PsiShortNamesCacheandAnnotatedElementsSearchalready see Kotlin light classes. A consequence worth documenting — and now in the README — is that theUseCaseannotation type itself may be declared in Kotlin.The usage searcher additionally maps each found method back to source through UAST. The Java-shaped search returns a light method for a Kotlin test, whose text ranges point at synthesized code rather than at anything the author wrote.
Two details worth a reviewer's eye
Kotlin nests the annotation name deeper than Java. From the name token, Java reaches its annotation in two hops; Kotlin takes five, through a type reference and a constructor callee. My first attempt capped the walk at four and silently produced no marker at all — the tests caught it, reading the code did not.
A Kotlin string value can look exactly like the annotation's name. The contents of
"UseCase"are a leaf whose text isUseCase, indistinguishable from the name token, so a naive port marks@UseCase(scenario = "UseCase")twice. The guard is that the token's parent must be a reference;testKotlinStringValueMatchingTheAnnotationNameIsNotMarkedpins it.Tests
./gradlew buildis green on IntelliJ IDEA 2026.1 — 51 tests, no compiler warnings. Four are new, mirroring the existing Java cases: the Kotlin gutter icon, the string-leaf trap above, the inspection in both directions, andUseCaseIndex.findTestMethodsresolving a Kotlin@UseCase(which also pins that light-method attribute reading works in K2 mode).The two Kotlin inspection tests assert on highlight descriptions rather than through
checkHighlighting: the light test project has no JDK, so Kotlin cannot resolvejava.lang.Stringin the Java-declared annotation and reports a type mismatch on every argument — noise unrelated to the inspection.Left to you
The version stays at
0.8.1and I added nochangeNotesentry, since releases are yours to cut.🤖 Generated with Claude Code