Open
Conversation
|
Formatting check succeeded! |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #116 +/- ##
============================================
+ Coverage 55.21% 56.06% +0.85%
+ Complexity 299 278 -21
============================================
Files 46 44 -2
Lines 1543 1170 -373
Branches 189 159 -30
============================================
- Hits 852 656 -196
+ Misses 618 442 -176
+ Partials 73 72 -1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
closes #114
Migrate
cql-language-serverfrom Java to Kotlin and remove Spring BootSummary
This PR converts the entire
cql-language-servercodebase from Java to Kotlin and removes Spring Boot. All 236 tests pass. The extension has been verified end-to-end in VS Code (hover, diagnostics, formatting, Execute CQL, View ELM).This is a foundational change. The Kotlin conversion is the first step on the path to Kotlin Multiplatform, which is the prerequisite for our 2026 goal of supporting pure JavaScript VS Code plugin usage — eliminating the Java dependency for end users entirely.
What changed
161 files changed — ~7,605 lines of Java deleted, ~6,473 lines of Kotlin added. The net reduction reflects Kotlin's conciseness.
Every module was converted:
core/—ContentService,Converters,Urisand their testsls/server/— all ~35 files: events, utilities, content services, managers, providers, visitors, plugin interfaces, commands, repository, and servicesls/service/— entry point replaced:Main.java+LanguageClientAppender.java→main.kt+LanguageClientAppender.kt;application.propertiesdeleteddebug/server/,debug/service/,plugin/debug/— DAP protocol files, debug service entry point, and debug plugin all convertedspring-boot-maven-pluginreplaced withmaven-shade-plugin;kotlin-maven-pluginand ktlint via spotless (spotless-maven-plugin 2.44.0) added to rootpom.xml; kapt added tols/serverandplugin/debugfor annotation processingSpring Boot removed entirely.
ServerConfig.javaandPluginConfig.javadeleted. The ~12 beans are now wired manually inmain.kt(114 lines).ServiceLoaderhandles plugin discovery as before.Test infrastructure simplified.
TestConfig.java,@SpringBootTest, and@Autowiredremoved. All tests use direct instantiation, following the pattern already established inHoverProviderTest.Test coverage expanded. The migration added new test classes for previously-untested components:
ActiveContentService,FileContentService,FederatedContentService,Diagnosticsutilities,CompilerOptionsManager,FormattingProvider,ContentServiceSourceProvider, andLanguageServerintegration. Test count grew from 163 to 236.Visibility corrected for test access. Java's package-private visibility (default access modifier) has no direct Kotlin equivalent. Two methods that were package-private in Java were initially converted to
protected(subclass-only in Kotlin), which broke same-package test access. They are nowinternal— the correct Kotlin equivalent, meaning module-visible:CompilerOptionsManager.clearOptionsandActiveContentService.patch/searchActiveContent.Why we removed Spring Boot
Spring Boot was not being used for any of its typical benefits — no web server, no REST endpoints, no auto-configuration of business logic. It was present solely as a packaging and DI mechanism for ~12 beans. The cost was significant.
The classloader problem. Spring Boot's fat jar uses
LaunchedURLClassLoaderrather than the system classloader. This classloader is only attached to the main thread. Any work dispatched to a thread pool — ForkJoinPool,CompletableFuture.supplyAsync, coroutines — cannot load classes through it, including HAPI FHIR's model classes, parsers, and terminology resources. This is not a bug we can fix; it is a fundamental property of how Spring Boot packages JARs.This single issue:
ClassNotFoundException. The debugger has been paused for months because of this.Execute CQLlibrary loop was impossible for the same reason. Each library evaluation already constructs its own engine instance — the only thing blocking parallelism was the classloader.The replacement is simpler. The 12 beans form a linear dependency chain. Manual wiring in
main.ktis clearer than Spring reflection magic and removes the framework entirely.maven-shade-pluginproduces a standard fat jar with the system classloader — no special behavior, no surprises. Tests instantiate dependencies directly and are faster and easier to reason about.This is also the foundation for our 2026 goals. Spring Boot is JVM-only. Removing it is a prerequisite for the Kotlin Multiplatform path that eventually targets JavaScript — enabling the extension to run without any Java dependency.
What this enables (roadmap)
Immediate follow-on PRs (branches already built and tested)
feature/cql-debugger— DAP debugger, UAT confirmed working. Stacked on this branch, ready to merge after this lands.feature/cql-call-graph— CQL call graph command, pending UAT.feature/find-all-references—textDocument/references/ Shift+F12.feature/refine-hover-functionality— hover improvements.feature/code-navigation— go-to-definition and related navigation features.Near-term (new PRs)
src/main/java→src/main/kotlinacross all modules, once all.javafiles are gone. Single isolated commit.CqlCommandis now feasible. Each library already gets its own engine instance; the Spring Boot classloader was the only blocker.Stoppableinterface so services that hold resources (DiagnosticsServiceexecutor, EventBus registrations) can be torn down cleanly. Low urgency now (System.exitreclaims everything), mandatory before Kotlin/JS.InitializeParams.initializationOptions(startup) andworkspace/didChangeConfiguration(runtime).CqlWorkspaceService.didChangeConfigurationis already stubbed.Medium-term (KMP path)
clinical_quality_languageKMP port when it lands from the other team.Test plan
mvn testfromcql-language-server/— 236 tests passvscode-cql/package.jsoncql-language-server.versionto4.3.0-SNAPSHOT, press F5, verify