Repository navigation
feat(language_server): add support for intellij-lsp backend - #341
Draft
SparkyCloudy wants to merge 5 commits into
Draft
SparkyCloudy wants to merge 5 commits into
SparkyCloudy wants to merge 5 commits into
Conversation
…guageServer gateway
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.
Base Branch Note
This PR builds directly on top of PR #335 (
refactor(lsp): add JavaLanguageServer gateway seam). It implements the actual backend integration requested in #314 using the gateway architecture introduced in #335.Problem
PR #335 introduces the
JavaLanguageServergateway abstraction, its resolvers were still exclusively written for Eclipse JDT.LS. Supporting IntelliJ LSP (intellij-lsp.nvim) required addressing several architectural differences between how JDT.LS and IntelliJ LSP operate:1. Test scope resolution differences
Eclipse JDT.LS accepts workspace/project directories and an explicit parameter
{ scope = "test" }. In contrast, IntelliJ LSP (intellij.java.resolveLaunchandintellij.java.resolveBuildCommand) does not support a scope parameter — it infers execution scope purely from the document URI passed:target/classes) and production build commands (compile), missing test dependencies like JUnit/Mockito.src/test/**/*.java) triggers test scope, returningtarget/test-classes, test dependencies, andtest-compile.2. JDK binary vs JDK home directory
IntelliJ LSP's
resolveLaunchreturnsres.javaExecpointing directly to the project's configured Java binary (<jdk>/bin/javaorjava.exe). However, downstream consumers inneotest-java(command/binaries.lua) expect the root JDK directory so they can locate bothbin/javaandbin/javap(used for method ID disambiguation).3. External build command execution
Unlike JDT.LS which compiles internally within its language server process, IntelliJ LSP returns a CLI build command (e.g.
mvnw test-compileorgradle testClasses). This needs to be spawned asynchronously viavim.systemwithout blocking Neovim or violating fast-event / coroutine boundary rules.4. Client detection restricted to JDT.LS
client_provider.luawas hardcoded to look only forjdtls, causingneotest-javato fail during test execution when running with IntelliJ LSP even if the LSP client was initialized.Solution
This PR implements full, out-of-the-box support for IntelliJ LSP while preserving 100% backward compatibility for existing JDT.LS users.
1. Unified Gateway Dispatching (
init.lua)JavaLanguageServersymmetrically instantiates both JDTLS and IntelliJ resolvers. On each request, it inspectsclient_provider(cwd):client.name == "intellij", delegates to IntelliJ resolvers.Binaries,ClasspathProvider,LspCompiler) require no changes.2. Test-Scoped Document URI Resolution (
document_uri.lua)Added a helper that searches for a representative test file (
src/test/**/*.javaor*Test*.java) to supply to IntelliJ LSP commands.safe_globprioritizingnio.fn.globpathovervim.fn.globpathto avoidE5560: textlock is active or fast-event contexterrors when called within async coroutines.3. Dedicated IntelliJ Resolvers
intellij_java_home.lua: Extractsres.javaExecfromintellij.java.resolveLaunchand calls.parent():parent()to resolve the JDK root folder forbinaries.lua. Includes fallbacks toJAVA_HOMEandvim.fn.exepath("java"), cached per directory.intellij_classpath.lua: RetrievesclasspathandmodulePath(JPMS) in a single roundtrip fromintellij.java.resolveLaunchand combines them with any additional classpath entries into aClasspathvalue object with platform path separators.intellij_compile.lua: Requestsintellij.java.resolveBuildCommandand executes the returned CLI command viavim.system. Safely awaits completion only when running inside an active coroutine (coroutine.running() ~= nil).4. Multi-Client Detection in
client_provider.luaUpdated
client_provider.luato check both"intellij"and"jdtls". Retains the maintainer's existing assertions and buffer-preloading polling logic.5. Architecture Documentation (
ARCHITECTURE.md)Updated
ARCHITECTURE.mdto document the multi-LSP gateway, updating the dependency table, Flow 2 sequence diagram, and component layout.Files Changed
lua/neotest-java/core/language_server/init.lualua/neotest-java/core/language_server/document_uri.lualua/neotest-java/core/language_server/intellij_java_home.luajavaExeclua/neotest-java/core/language_server/intellij_classpath.luaclasspathandmodulePathfromresolveLaunchlua/neotest-java/core/language_server/intellij_compile.luaresolveBuildCommandviavim.systemlua/neotest-java/core/spec_builder/compiler/client_provider.luaintellijclient alongsidejdtlstests/unit/test_intellij_language_server_spec.luatests/unit/test_client_provider_spec.luaintellijclient detectionARCHITECTURE.mdTesting
Tested manually on:
belajar-java-resilience4j) withintellij-lsp.nvim.Verifications:
nvim --headless -u scripts/minimal_init.lua -c "lua MiniTest.run()"runs and passes all 209 unit tests cleanly (0 failures, 0 errors) in ~0.15s.7 new unit tests in
test_intellij_language_server_spec.luacomprehensively mock and test IntelliJ LSP request flows.Verified test discovery, test execution, and result tree rendering inside live Neovim via
<leader>tt.Zero regressions on existing JDT.LS test cases.
Disclosure
Co-authored with AI coding assistant (Google Antigravity).