PC version override: decouple PC artifact version from build target#95
Open
rochala wants to merge 3 commits into
Open
PC version override: decouple PC artifact version from build target#95rochala wants to merge 3 commits into
rochala wants to merge 3 commits into
Conversation
Adds a launch-time debugging knob to load the presentation compiler from a different scala3-presentation-compiler_3 version than the build target's own Scala version — without a recompile. - PcVersionOverride: per-module map (`-Dsls.pc.versions=mod=ver,...` / SLS_PC_VERSIONS, keyed by build-target display name) over a global default (`-Dsls.pc.version` / SLS_PC_VERSION); resolution falls back to the target's own Scala version. Read once at startup. - PresentationCompilerProvider.get resolves the effective version per module and logs when an override is in effect. - Combined with coursier's ivy2Local default repo, a locally publishLocal-ed dotty PC build is directly usable. - README: Debugging the presentation compiler. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The version override alone wasn't enough to actually load a PC built against a different Scala version than sls's bundled compiler. Three coupled fixes: - PcParentClassLoader: the PC's URLClassLoader used the host app loader as parent, so dotty.tools.* (e.g. InteractiveDriver) leaked from sls's bundled scala3-compiler (via scala3-tasty-inspector) while dotty.tools.pc.* loaded from the override jars -> NoSuchMethodError. The new parent has the bootstrap loader as parent and shares only the host<->PC bridge packages (scala.meta.pc, org.eclipse.lsp4j, com.google.gson), forcing dotty.tools.* and the stdlib to load from the PC's own jars. - build.mill: bump mtags-interfaces 1.6.3 -> 1.6.7 so the shared scala.meta.pc interface has the methods newer PCs call (e.g. sourcePathMode). - ServerImpl: 1.6.7 pulls a newer lsp4j where Diagnostic.getMessage is Either[String, MarkupContent]; add a chimney transformer unwrapping it to the plain String that lsp.Diagnostic.message expects. Also switches the PC provider's two log lines from IO.consoleForIO to slf4j, matching the rest of the app. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
What
A launch-time knob to load the presentation compiler from a different
scala3-presentation-compiler_3version than the build target's own Scala version — and the classloader/dependency work needed to actually make such a PC load. Useful for testing a locally-built dotty PC against a real project.The override (commit 1)
PcVersionOverride— resolved once at startup from system properties (env fallback):-Dsls.pc.version=<v>/SLS_PC_VERSION— global default for every module.-Dsls.pc.versions=<module>=<v>,…/SLS_PC_VERSIONS— per-module map, keyed by build-target display name, taking precedence over the global.PresentationCompilerProvider.getresolves the effective version per module and logs (slf4j) once per PC creation when an override is active.ivy2Localrepo means apublishLocal-ed snapshot resolves directly.Making it actually load (commit 2)
The override alone wasn't enough — a PC built against a different Scala version than sls's bundled compiler failed to load. Three coupled fixes:
PcParentClassLoader— the PC'sURLClassLoaderused the host app loader as parent, sodotty.tools.*(e.g.InteractiveDriver) leaked from sls's bundledscala3-compiler(viascala3-tasty-inspector) whiledotty.tools.pc.*loaded from the override jars →NoSuchMethodError. The new parent has the bootstrap loader as parent and shares only the host↔PC bridge packages (scala.meta.pc,org.eclipse.lsp4j,com.google.gson), forcingdotty.tools.*and the stdlib to load from the PC's own jars.build.mill— bumpmtags-interfaces1.6.3 → 1.6.7 so the sharedscala.meta.pcinterface has the methods newer PCs call (e.g.sourcePathMode).ServerImpl— 1.6.7 pulls a newer lsp4j whereDiagnostic.getMessageisEither[String, MarkupContent]; a chimney transformer unwraps it to theStringthatlsp.Diagnostic.messageexpects.Note for review
Commit 2 globally bumps the host's
mtags-interfaces(and transitively lsp4j) to make a newer PC line work. That's an intended dependency move, but worth a sanity check that 1.6.7 is the right floor.Why module-keyed
A project has multiple modules; pinning the PC per module (with a global fallback) lets you isolate debugging to one target in a cross-built project. The key is the build-target display name, logged on PC creation so it's discoverable.
Future work
The override is currently static (read at startup). The design supports making it runtime-updatable via an LSP endpoint (
workspace/didChangeConfigurationor a custom command) with no restart — hold it in aRef, update on the endpoint, callinvalidateCompilers(). Not in this PR.Test
PcVersionOverrideSpeccovers map parsing (incl. malformed entries) and the precedence chain../mill sls.testis fully green.🤖 Generated with Claude Code