Skip to content

ADFA-4823: Kotlin go-to-definition in the K2 LSP - #1597

Merged
itsaky-adfa merged 20 commits into
stagefrom
worktree/ADFA-4823
Jul 31, 2026
Merged

ADFA-4823: Kotlin go-to-definition in the K2 LSP#1597
itsaky-adfa merged 20 commits into
stagefrom
worktree/ADFA-4823

Conversation

@itsaky-adfa

@itsaky-adfa itsaky-adfa commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Go-to-definition in the K2 Kotlin LSP: jump from a Kotlin reference to its declaration, same-file, inter-file and inter-module.

Jira: ADFA-4823

Requirements and scope: docs/features/kotlin-goto-definition.md. Structural decision: ADR 0010 - navigation resolves through the Analysis API, not the symbol index.

What it does

  • A Go to definition item in the Kotlin code-actions menu, mirroring Java's, with its own tooltip tag (editor.codeactions.kotlin.gotodef). The tooltip row lives in the tooltips database, not this repo - hand-off item.
  • Covers name references and convention references (a + b, a[i], by lazy, destructuring, for loops), plus labels and KDoc links. Workspace .java and build/generated/** targets included.
  • Multi-candidate results are deduplicated and ordered into the existing panel; ranges cover the declaration's name identifier.

Binary symbols (stdlib, framework, jars) are out of scope - no decompiler on device, so those report "Definition not found". Find-usages is ADFA-4824 and reuses the caret helper unchanged.

Caret mapping is split from resolution: ReferenceAtCaret.kt is pure PSI, so the caret rules test without an analysis session and ADFA-4824 imports it as-is. GoToDefinition.kt owns resolution, filtering, ranges and cancellation.

Review order

Arranged for review-by-commit. The last four came out of a code review of the rest:

Commit
d3f15d2 ignoreFailures now gates on whether the coverage/Sonar chain was requested. One failing test used to skip jacocoAggregateReport and sonarqube entirely, so the nightly analysis uploaded an empty artifact.
53b02df -XX:HeapDumpPath under build/test-heapdumps/; unpathed, a worker OOM dropped up to 1g into the source tree.
bc72b0a Three lookup failures: .kts let UnsupportedOperationException reach the editor; mainReference is typed nullable but throws on a KtReferenceExpression with no contributed reference; the preemption retry reused a KtFile the refresh had unregistered.
3251f2c Fixture: disposal errors no longer replace the test's own failure, and a constructor throw no longer leaks the process-wide KotlinCoreApplicationEnvironment.

d3f15d2 drops the per-module test mute list - it only existed to protect the analysis run, which the task-name check now handles, so :gradle-plugin, :lsp:java and :termux:termux-app gate ordinary builds again and their existing failures will surface.

Testing

flox activate -d flox/local -- ./gradlew :lsp:kotlin:testV7DebugUnitTest - passing. ReferenceAtCaretTest (caret rules), GoToDefinitionTest (resolution rows, all three scopes, dedup, ranges, cancellation), FindDefinitionRequestTest (request path), InterModuleResolutionTest.

Not unit-tested: the preemption retry (needs a second concurrent interactive request the fixture can't schedule) and the action's prepare() path, consistent with the other Kotlin actions. Both covered by on-device QA - see "Steps to QA" on the ticket.

Known gaps

  • Cross-file ranges can be one edit stale. With unsaved edits in the target file, KtSymbolIndex.getKtFile falls through to the on-disk PSI (it runs under project.read and must not block on a refresh needing project.write), so the caret can land off by the lines inserted above. Fixing it means re-locating the declaration in the live PSI.
  • A caret exactly on [ or ( resolves the convention host, not the identifier before it - deliberate and asserted, but list[0] reports nothing when get is in a jar.
  • DocumentUtils.isKotlinFile still stats the file on the UI thread in every code action's prepare(). Pre-existing, shared with Java; worth its own ticket.

The :lsp:kotlin suite could not complete: it OOMed part-way through, and the
OOM then deadlocked Gradle's TestWorker instead of failing the task.

Two causes, two fixes:

- KtLspTestRule never disposed the test environment. The TODO'd env.close()
  failed because disposal needs an IntelliJ write action, which our own
  project.write lock does not supply. Every test therefore leaked a whole
  KotlinCoreApplicationEnvironment (refcounted, process-wide static).
- The test-worker heap was Gradle's 512m default, too small for the
  Robolectric + Kotlin Analysis API suites regardless of the leak.

Also stops muting test failures everywhere: ignoreFailures now applies only
to the modules whose tests are known to fail, so a green build means the
suite actually passed. :lsp:kotlin is not in that set.

Picked up from the stage worktree, where these fixes were written but not yet
committed; carried here so this branch's tests can gate on a real result.
Reconciled onto the current KtLspTestRule, which this branch had already
reworked for multi-module specs.

:lsp:kotlin now reports 184 tests, 0 failures, 0 skipped.
…exed

Workspace .java sources could not be resolved from Kotlin in the standalone
Analysis API environment: JavaPsiFacade.findClass returned null and a type
reference to a workspace Java class resolved to nothing.

Cause: isSourceModule was `this is KtSourceModule`, a check against one
concrete class. Any other source-module implementation was therefore
classified as a library, so in AbstractCompilationEnvironment.initialize the
javaSourceRoots partition came out empty and javaFileManager/corePackageIndex
never got the source root on their classpath. The same modules were also fed
into libraryRoots as BINARY roots.

Ask the Analysis API's own question instead (KaSourceModule). Both
KtSourceModule and TestKtSourceModule implement it; KtLibraryModule
implements KaLibraryModule, so library classification is unchanged. This is
the only nominal check of its kind in the tree.

Also add KtLspTestEnvironment.createFile, returning PsiFile: createSourceFile
narrows to KtFile and threw for .java sources, so no test could create one.
createSourceFile now delegates to it.

Together these make Kotlin-to-Java navigation testable, which the
go-to-definition work needs for acceptance criterion 5.

:lsp:kotlin reports 212 tests, 0 failures, 0 skipped.
The go-to-definition work lands with its governing decision and requirements
only in a working tree, so neither is reviewable alongside the code.

Add ADR 0010 (navigation resolves via the Analysis API and PSI, never the
symbol indexes - the indexes store no declaration offsets and answer by name
rather than by resolution) and its row in the ADR index, plus the feature's
requirements and acceptance criteria.

R10 is corrected while committing it: prepare() adds no lock, index or
analysis work, but it is not filesystem-free, because
BaseKotlinCodeAction.prepare calls DocumentUtils.isKotlinFile, which stats
the file. That is pre-existing and shared by every Java and Kotlin code
action; the doc now says so rather than claiming an invariant that does not
hold.
locationOfPsi derived a target's path from its virtualFile, which is
non-physical (protocol "mock" in production, null under Robolectric)
for any declaration living in the file the user has open -
KtSymbolIndex.refreshToCurrent builds that live KtFile via
parser.createFile and never gives it a real on-disk virtualFile. Every
same-file (and any other open-file) declaration was silently dropped.

Derive the path from the live KtFile's backingFilePath first, falling
back to the VFS (still gated on protocol == "file") only for
declarations reached outside the live-document cache. Binaries stay
excluded on the rawReferenceLocation path too: backingFilePath is only
ever set in KtSymbolIndex.refreshToCurrent for workspace sources
opened as active documents, so a library/binary KtFile never carries
it and falls through to the unchanged, still-guarded VFS branch.

Add a regression test exercising the live-document path end to end
through findDefinitionAt (open the file, then request its own
declaration). Making it faithful required KtLspTestEnvironment's
in-memory KtFiles to be physical the way production's are
(enableParserEventSystem), which the test harness had hardcoded off
for every test; expose it as an opt-in override, default unchanged, so
only this test's live-document scenario is affected.
…tale comments

findDefinitionAt now retries once, with a fresh ScheduledCancelChecker,
when the analysis is preempted by a concurrent higher-or-equal-priority
request (AnalysisPreemptedException). INTERACTIVE requests supersede
same-priority ones, so a completion or signature-help lookup could
preempt an in-flight definition request while it is still alive,
surfacing "Definition not found" for a reference that resolves fine. A
genuine cancellation still returns empty immediately, without retrying.

GoToDefinitionTest's multi-candidate test used a resolvable overloaded
call, which resolves to exactly one symbol - distinctBy/sortedWith in
definitionLocations went untested. Replaced it with a for-loop over a
workspace-defined iterator (hasNext/next/iterator all workspace
sources, so none get filtered as stdlib), asserting three distinct,
ordered locations.

Comment fixes:
- GoToDefinitionAction: corrected the claim that nothing in prepare()
  touches disk - the base class's isKotlinFile does stat the file, a
  pre-existing issue shared by every Kotlin/Java code action.
- KtModule.isSourceModule: the KDoc implied a shipped classification
  bug; in production KtSourceModule is the only KaSourceModule, so the
  nominal and structural checks always agreed there. The fix only
  changes TestKtSourceModule's classification and hardens the
  predicate for future source-module implementations.
- ReferenceAtCaret.MAX_CLIMB: the comment credited the cap with
  stopping a caret on a declaration's name from climbing into an
  enclosing call, but that's several levels beyond the cap - the
  intervening ancestors are simply not resolvable. The cap's actual
  job is bounding the walk to what the reference kinds need.
- findDefinitionAt KDoc: noted why its context parameter is the
  abstract environment rather than the concrete one (so the test
  environment can drive it).
- GoToDefinitionTest's property-delegate test: added the same
  tolerance comment as the for-loop test below it, explaining why
  extra candidates (setValue/provideDelegate) are acceptable.
`jacocoAggregateReport` dependsOn every subproject's `testV8DebugUnitTest`, and
`sonarqube` dependsOn that report, so a single failing test task skipped both -
even under `--continue`. The analyze workflow then uploaded an empty
`jacoco-report` artifact and SonarCloud received no analysis for the commit.

Gate `ignoreFailures` on whether the analysis chain is what was requested, so
the coverage/Sonar run always produces a report while every ordinary build still
fails on a failing test.

That also removes the reason for the per-module mute list: it existed only to
keep those modules from breaking the analysis run, which the task-name check now
handles, so their suites gate the build again like everything else.
A test worker's working dir defaults to the module directory, so the new
-XX:+HeapDumpOnOutOfMemoryError had nowhere to put a dump but the source tree -
up to maxHeapSize (1g) per OOM, untracked and not covered by .gitignore. On CI
several such dumps can exhaust the runner disk and turn one test OOM into an
unrelated "No space left on device".

Point -XX:HeapDumpPath at build/test-heapdumps/<task>.hprof, created in doFirst
because the JVM will not create a missing dump directory itself.
…es, preemption

Three ways the lookup failed where it should have answered:

- `DocumentUtils.isKotlinFile` accepts `.kts`, and the editor attaches the Kotlin
  server to build scripts, so a Go-to-definition there reached
  `CompilationKind.Script` and let `UnsupportedOperationException` escape into the
  editor as an error flash. The path-based `compilationEnvironmentFor` is already
  nullable; return null for a script instead of throwing, which also fixes the
  same escape from `complete`, `signatureHelp` and the file-event handlers.

- `mainReference` is typed nullable but on a `KtReferenceExpression` it is
  `references.firstIsInstance()`, which throws when no `KtReference` is
  contributed. Reading it last and guarded keeps a throw from aborting the whole
  ancestor climb before the convention-host checks run.

- The preemption retry reused the `KtFile` captured before the preemption. What
  preempted the lookup also refreshed the live PSI and unregistered that file, so
  the retry analyzed a dangling instance and reported "definition not found" for a
  reference that resolves. Await the current file per attempt.

Also drop the feature doc's claim that `findDefinition` is still a stub.
…init throw

Disposal ran bare in the rule's `finally`, so a throw from `close()` - a timed-out
index drain, a Disposer error - replaced the exception already in flight and JUnit
reported the fixture instead of the assertion that actually broke. Attach disposal
errors as suppressed on the test's own failure, and only rethrow them when the test
passed.

The environment was also assigned to the field only after its constructor
returned, so a throw from `initialize()` - and the module specs added several new
ones - left `::env.isInitialized` false, close() unreachable, and the refcounted,
process-wide `KotlinCoreApplicationEnvironment` leaked for the rest of the suite:
one misspelled `dependsOn` would reproduce the very OOM this fixture work fixed.
Release it from the constructor, where the half-built instance is still reachable.
@itsaky-adfa itsaky-adfa self-assigned this Jul 29, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@itsaky-adfa
itsaky-adfa requested a review from a team July 29, 2026 19:12
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough
  • Added Kotlin K2 LSP go-to-definition support using the Kotlin Analysis API and PSI.
  • Supports same-file, cross-file, cross-module, workspace Java, and generated-source navigation, including conventions, labels, and KDoc links.
  • Added caret/reference mapping, cancellation handling, preemption retry, result filtering, deduplication, ordering, and declaration-name ranges.
  • Added a Kotlin go-to-definition code action and tooltip tag.
  • Expanded multi-module test fixtures and coverage for navigation, ranges, cancellation, conventions, and Java resolution.
  • Added feature requirements and ADR documentation.
  • Improved test failure handling, worker memory limits, OOM heap dumps, environment cleanup, module classification, and script handling.
  • Kotlin tests pass: 212 tests, 0 failures, 0 skipped.
  • Risks: on-device QA remains required for preemption retry and action preparation; unsaved cross-file edits may produce stale ranges; convention navigation may fail when the caret is exactly on [ or (; binary-library symbols and decompilation are unsupported.
  • Best-practice concern: code-action preparation still performs pre-existing file-stat operations on the UI thread.

Walkthrough

Adds Kotlin go-to-definition through Analysis API and PSI, exposes it as a Kotlin editor action, documents its behavior, expands LSP fixtures for multi-module testing, and adds broad navigation coverage. Gradle test execution also gains conditional failure handling and OOM heap-dump diagnostics.

Changes

Kotlin go-to-definition

Layer / File(s) Summary
Navigation contracts and specification
docs/adr/0010-navigation-resolves-via-analysis-api.md, docs/adr/README.md, docs/features/kotlin-goto-definition.md
Documents Analysis API and PSI resolution, supported scopes, exclusions, result handling, cancellation, and acceptance criteria.
Configurable multi-module test environment
lsp/kotlin/src/test/.../fixtures/*
Adds named source modules, dependency construction, parser-event configuration, module-aware file creation, and failure-safe environment cleanup.
Caret and Analysis API resolution
lsp/kotlin/src/main/.../compiler/*, lsp/kotlin/src/main/.../navigation/*
Resolves caret references, handles convention and PSI fallbacks, maps workspace declarations to locations, deduplicates results, and handles cancellation or preemption.
Editor action and LSP wiring
idetooltips/src/main/.../TooltipTag.kt, lsp/kotlin/src/main/.../KotlinCodeActionsMenu.kt, lsp/kotlin/src/main/.../KotlinLanguageServer.kt, lsp/kotlin/src/main/.../actions/GoToDefinitionAction.kt
Registers the Kotlin go-to-definition action and delegates LSP definition requests to the compilation environment.
Navigation behavior tests
lsp/kotlin/src/test/.../navigation/*, lsp/kotlin/src/test/.../KotlinCodeActionTooltipTagTest.kt, lsp/kotlin/src/test/.../fixtures/InterModuleResolutionTest.kt
Covers caret handling, Kotlin constructs, cross-file and cross-module navigation, live documents, cancellation, ordering, ranges, tooltip mapping, and library exclusion.

Test runtime diagnostics

Layer / File(s) Summary
Conditional test execution and heap diagnostics
build.gradle.kts
Makes test failure ignoring conditional on analysis tasks, sets a 1 GB test heap, and enables per-task OOM heap dumps.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Editor
  participant KotlinLanguageServer
  participant CompilationEnvironment
  participant AnalysisAPI
  participant WorkspaceFiles
  Editor->>KotlinLanguageServer: textDocument/definition
  KotlinLanguageServer->>CompilationEnvironment: findDefinitionAt
  CompilationEnvironment->>AnalysisAPI: resolve caret reference
  AnalysisAPI->>WorkspaceFiles: map declaration to location
  WorkspaceFiles-->>Editor: return definition locations
Loading

Possibly related PRs

Suggested reviewers: dara-abijo-adfa, jatezzz

Poem

A rabbit hops through Kotlin code,
And finds each symbol’s hidden road.
PSI lights the caret’s way,
While tests keep bugs at bay.
Heap dumps rest beneath the build—
Navigation’s map is filled!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.16% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: Kotlin go-to-definition support in the K2 LSP.
Description check ✅ Passed The description is directly related to the changeset and matches the implemented navigation and documentation updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch worktree/ADFA-4823

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/InterModuleResolutionTest.kt (1)

1-52: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

JUnit4 @Test used instead of JUnit Jupiter in this new test.

This new test extends the JUnit4 RunWith(RobolectricTestRunner::class)-based KtLspTest/KtLspTestRule fixture, so it can't independently adopt JUnit Jupiter without migrating the whole shared fixture stack (used by the rest of the navigation test suite). Worth tracking as a follow-up if/when the fixture itself is modernized, rather than blocking this PR.

As per coding guidelines, **/src/test/**/*.{kt,java} should "Use JUnit Jupiter, Truth, MockK for new tests, Mockito-Kotlin where legacy conventions require it, and Robolectric for framework-dependent JVM tests."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/InterModuleResolutionTest.kt`
around lines 1 - 52, Keep InterModuleResolutionTest on JUnit4 using
org.junit.Test because KtLspTest and KtLspTestRule depend on the shared
Robolectric JUnit4 runner; do not migrate this test independently to JUnit
Jupiter. Track fixture-wide JUnit migration separately rather than changing the
test framework here.

Source: Coding guidelines

lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/navigation/ReferenceAtCaret.kt (1)

94-108: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Narrow the runCatching in isResolvable().

runCatching { mainReference != null } catches any Throwable, so unrelated PSI/IO exceptions or Errors can be reported as plain “not resolvable” without visibility. Catch only the expected firstIsInstance() failure case instead of wrapping the whole access.

♻️ Proposed narrowing
 private fun KtElement.isResolvable(): Boolean =
 	this is KtCallExpression ||
 		this is KtArrayAccessExpression ||
 		this is KtPropertyDelegate ||
 		this is KtForExpression ||
-		runCatching { mainReference != null }.getOrDefault(false)
+		try {
+			mainReference != null
+		} catch (e: NoSuchElementException) {
+			false
+		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/navigation/ReferenceAtCaret.kt`
around lines 94 - 108, In KtElement.isResolvable(), narrow the exception
handling around mainReference access so it catches only the expected
missing-reference exception thrown by firstIsInstance(), rather than using
runCatching, which also suppresses unrelated Throwables and Errors. Preserve the
existing false result for that expected failure and let other failures
propagate.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/navigation/ReferenceAtCaret.kt`:
- Around line 94-108: In KtElement.isResolvable(), narrow the exception handling
around mainReference access so it catches only the expected missing-reference
exception thrown by firstIsInstance(), rather than using runCatching, which also
suppresses unrelated Throwables and Errors. Preserve the existing false result
for that expected failure and let other failures propagate.

In
`@lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/InterModuleResolutionTest.kt`:
- Around line 1-52: Keep InterModuleResolutionTest on JUnit4 using
org.junit.Test because KtLspTest and KtLspTestRule depend on the shared
Robolectric JUnit4 runner; do not migrate this test independently to JUnit
Jupiter. Track fixture-wide JUnit migration separately rather than changing the
test framework here.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f934f26b-9a8a-42e6-ba26-764d536a0ec8

📥 Commits

Reviewing files that changed from the base of the PR and between ee6d454 and 3251f2c.

📒 Files selected for processing (21)
  • build.gradle.kts
  • docs/adr/0010-navigation-resolves-via-analysis-api.md
  • docs/adr/README.md
  • docs/features/kotlin-goto-definition.md
  • idetooltips/src/main/java/com/itsaky/androidide/idetooltips/TooltipTag.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/KotlinCodeActionsMenu.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/KotlinLanguageServer.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/actions/GoToDefinitionAction.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/Compiler.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/compiler/modules/KtModule.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/navigation/GoToDefinition.kt
  • lsp/kotlin/src/main/java/com/itsaky/androidide/lsp/kotlin/navigation/ReferenceAtCaret.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/KotlinCodeActionTooltipTagTest.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/InterModuleResolutionTest.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTest.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestEnvironment.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/KtLspTestRule.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/fixtures/TestSourceModuleSpec.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/navigation/FindDefinitionRequestTest.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/navigation/GoToDefinitionTest.kt
  • lsp/kotlin/src/test/java/com/itsaky/androidide/lsp/kotlin/navigation/ReferenceAtCaretTest.kt

@itsaky-adfa
itsaky-adfa merged commit 3b6b729 into stage Jul 31, 2026
4 checks passed
@itsaky-adfa
itsaky-adfa deleted the worktree/ADFA-4823 branch July 31, 2026 11:28
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