Skip to content

Elvis/vscode extension#445

Merged
ezekielelvis merged 12 commits into
masterfrom
elvis/vscode-extension
May 23, 2026
Merged

Elvis/vscode extension#445
ezekielelvis merged 12 commits into
masterfrom
elvis/vscode-extension

Conversation

@ezekielelvis
Copy link
Copy Markdown
Contributor

[WIP]This pull request introduces significant improvements to the VS Code extension for XTC, focusing on enhanced debugging support, improved task and command integration, and better developer experience through configuration and documentation updates. The main changes are the addition of a Debug Adapter Protocol (DAP) integration, new commands and tasks for running and managing XTC modules, and updates to build scripts and configuration files to support these features.

Debugging and Task Integration

  • Added a new Debug Adapter Protocol (DAP) integration, including a XtcDebugAdapterDescriptorFactory and XtcDebugConfigurationProvider in debug-adapter.ts, enabling users to debug XTC modules directly from VS Code. This includes logic to find the Java executable, launch the DAP server JAR, and provide debug configuration defaults.
  • Introduced a new task provider and command registrations in commands.ts, allowing users to run XTC modules, create new projects, and show language server output directly from the command palette.
  • Updated package.json to declare new commands (xtc.runModule, xtc.restartServer, xtc.showServerOutput), a custom XTC task type, and a new debugger type (xtc) with configuration snippets and attributes for module debugging. [1] [2] [3]

Build and Launch Configuration

  • Updated the build.gradle.kts build script to copy the DAP server JAR into the extension's server directory, and ensured that both the LSP and DAP servers are included in packaging and assembly tasks. The VS Code launch command now opens the test fixtures folder for easier testing. [1] [2] [3] [4]
  • Added and updated VS Code workspace configuration files (.vscode/launch.json, .vscode/tasks.json) to support extension development, building, and debugging workflows for both the root and extension subfolders. [1] [2] [3] [4]
  • Updated .gitignore to exclude .vscode-test/ from version control.

Documentation and Developer Experience

  • Enhanced the README.md with clearer setup instructions, improved project structure documentation, and step-by-step guides for building, running, and testing the extension locally. [1] [2] [3] [4] [5] [6]

These changes collectively make the XTC VS Code extension much more robust and user-friendly, especially for debugging and automation workflows.

@ezekielelvis ezekielelvis requested a review from lagergren April 25, 2026 14:30
Comment thread .vscode/launch.json Outdated
Comment thread javatools/bin/default/README.md Outdated
Comment thread javatools/bin/default/.classpath Outdated
Comment thread javatools/bin/default/build.gradle.kts Outdated
Comment thread javatools/bin/default/LICENSE Outdated
Comment thread lang/vscode-extension/build.gradle.kts
Comment thread lang/vscode-extension/src/lsp-client.ts
@ezekielelvis ezekielelvis marked this pull request as ready for review May 6, 2026 13:24
@ezekielelvis ezekielelvis requested review from ggleyzer and lagergren May 7, 2026 15:06
Copy link
Copy Markdown
Collaborator

@ggleyzer ggleyzer left a comment

Choose a reason for hiding this comment

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

I'm really out of my depth here and would completely defer to Markus.

My only comment is: this PR seems to be an indicator that it wasn't the best idea to keep the plugin as a part of the xvm repo. May be we should start a new "plugin" repo using this PR?

@lagergren
Copy link
Copy Markdown
Contributor

I'm really out of my depth here and would completely defer to Markus.

My only comment is: this PR seems to be an indicator that it wasn't the best idea to keep the plugin as a part of the xvm repo. May be we should start a new "plugin" repo using this PR?

There is nothing in the PR after updates that leaks out of lang, and as we have talked a lot about there is a migration plan to standalone implementation when I have finished the type adapter work, and there is a good reason that this lives under lang until that integration path is finished.

I am still in deployment hell but I will try to review tonight or tomorrow. Now, however, it looks safe, in that it doesn't bleed out state into the rest of the code and lives self contained under lang just like the intellij plugin and the lsp server that both use. The only concern I have is about the node dependency potentially being resolved even if we are not creating a vscode-plugin build, and that, like the intellij toolkit, also is a very large download/install (although cached of course):

@lagergren lagergren force-pushed the elvis/vscode-extension branch from 011d486 to cffa239 Compare May 10, 2026 11:38
@lagergren
Copy link
Copy Markdown
Contributor

There is an issue with the CI / build and test trying to resolve the libs.versions.toml gradle plugin but fails. Not sure why, but I think that it needs to live only under lang an only when the vscode plugin is being built.

@lagergren
Copy link
Copy Markdown
Contributor

Where:
Build file '/home/runner/work/xvm/xvm/lang/vscode-extension/build.gradle.kts' line: 5

  • What went wrong:
    31 actionable tasks: 11 executed, 2 from cache, 18 up-to-date
    Script compilation error:

    Line 5: alias(libs.plugins.langNodeGradle)
    ^ Unresolved reference 'langNodeGradle'.

1 error

Comment thread lang/vscode-extension/build.gradle.kts
@lagergren
Copy link
Copy Markdown
Contributor

The issue is that one of x files no longer parse equivalently between the lsp parser and the Java parser. This is likely an issue in treesitter caused by someone changing parser behavior or grammar in master, but not in the treesitter grammar template. It hasn't got anything to do with your branch. If you want, add the falling file to the skip list documented as a known outage and we can approve this for merge.

The treesitter grammar validation tests only run for a branch that changes stuff in the Lang tree. This means that I think the test would fail if running in master itself. I am on the road most of the day, but if you can confirm thst validateTreeSitter grammar fails in master too with Lang attached, then the theory is confirmed. You can check the commit.yml to see how to run the validation test, or you could just trigger a GitHub workflow on master with workflow dispatch (manually) with the "test lang" boxes checked and it should do it automatically for you.

I will take a look in a few hours when I return to civilization.

@lagergren lagergren force-pushed the elvis/vscode-extension branch 2 times, most recently from 64bdc75 to 5bb10a0 Compare May 23, 2026 06:48
@lagergren
Copy link
Copy Markdown
Contributor

Why the tree-sitter validation went red on this PR but is green on master

Short version: this isn't a tooling or grammar regression — it's two new XTC syntax patterns that were added to the manualTests corpus between May 6 and May 17 and that the tree-sitter grammar never had test cases for. The path-filter gate in .github/workflows/commit.yml (dorny/paths-filter on lang/**) hid both of them from master CI because the PRs that introduced them only touched manualTests/ and javatools/.

Date Commit Test addition
2026-05-06 0120712a1 Fix NameExpression code production for parameterized virtual child classes generics.x:27Type t2 = Base<Int>.Child2<String>; (value-position virtual-child type with generic args)
2026-05-17 91f6d7d96 Fix a compiler exception (#463) annos.x:141annotation PreComputed(...) into Predicate { ... } inside a method body (local annotation declaration)

Both PRs were compiler bugfixes that added a single new line of XTC to verify the fix. Because neither touched lang/**, the tree-sitter validation step on master was skipped (path-filter conclusion: lang=false). On this PR, the lang/vscode-extension/** changes trip the same filter (lang=true), so the validation step runs — and surfaces both pre-existing latent failures.

The skip lists (treeSitterParseSkipList.parked.txt, treeSitterParseSkipList.intentional.txt) and the grammar template itself were unchanged between PR #452 (May 1, last grammar work) and the May 6 / May 17 corpus additions. The comment in parked.txt claiming "generics.x parses cleanly now — removed from this list" is incidentally misleading: git log -S "manualTests/src/main/x/generics.x" -- treeSitterParseSkipList.parked.txt returns empty, so generics.x was never actually in any skip list.

Fix in this PR: two grammar template edits — annotation_declaration added to _statement, and member_type (with-type-arguments form at prec.left(MAX_PRECEDENCE_PLUS_3)) added to _expression. Local test now reports 881 passed, 0 failed (was 879 / 2).

Suggested follow-up (not in this PR): the path-filter for the tree-sitter step in commit.yml could also include manualTests/**/*.x so that new corpus shapes get grammar-checked on master, not just on PRs that happen to touch lang/**. That would have caught both regressions at the source.

ezekielelvis and others added 8 commits May 23, 2026 08:49
- Implemented .gitignore to exclude unnecessary files
- Created launch.json for debugging configurations
- Added tasks.json for npm scripts to compile and watch
- Updated README.md with project structure and local testing instructions
- Enhanced build.gradle.kts to copy DAP server JAR and adjust packaging tasks
- Modified package.json to include new commands and configuration options
- Developed commands.ts to register commands for running modules and creating projects
- Introduced debug-adapter.ts for DAP integration
- Refactored extension.ts to manage activation and language client lifecycle
- Implemented java.ts for Java discovery and JVM argument building
- Created lsp-client.ts to manage the language client and its lifecycle
- Added status-bar.ts for displaying server status in the VS Code status bar
- Developed task-provider.ts for managing custom tasks related to XTC modules
…able detection

- Introduced a new properties file for error messages with comprehensive error codes and descriptions.
- Updated package.json to associate .x files with the xtc language and added workspaceContains activation event.
- Refactored command registration to validate project names using a dedicated function.
- Enhanced the extension to ensure .x files are correctly associated with the xtc language upon opening.
- Improved Java executable detection by consolidating logic and handling errors more gracefully.
- Updated LSP client to manage server state more effectively, including handling crashes and ensuring proper startup.
- Added logging for server startup details and improved error handling for missing Java installations.
refactor: remove VS Code launch and task configurations

chore: update build.gradle.kts to use node plugin for npm tasks

feat: add jdk-utils dependency for Java discovery

fix: enhance findJavaExecutable to support JRE download and caching

feat: update debug adapter to use async Java executable discovery

fix: improve language server startup status indication

refactor: streamline Java discovery process and add download functionality

fix: ensure proper handling of Java executable paths and permissions

chore: update LSP client to handle async Java executable resolution

Co-authored-by: Copilot <copilot@github.com>
ezekielelvis and others added 2 commits May 23, 2026 08:49
- Enhanced README with detailed features and installation instructions.
- Removed icon copying task from build.gradle.kts.
- Updated package.json to include additional categories and keywords, and corrected icon paths.
…ls in expression position

Closes two grammar gaps that surface as parse errors against the
manualTests corpus (CI hides these on master because the validation
step is gated on path-filter `lang/**`):

* annos.x:141 — `annotation Foo(...) into Bar { ... }` inside a method
  body. Local class/interface/mixin/service declarations were already in
  the `_statement` choice; `annotation_declaration` was not. Added.

* generics.x:27 — `Base<Int>.Child2<String>` as a value-position type
  literal. `member_type` was reachable from `_non_bi_type` only, so it
  was never tried in expression position. Added to `_expression` next
  to `$.generic_type` (the symmetric case for non-virtual-child type
  literals).

  The with-type-arguments form of `member_type` is split into its own
  alternative at `prec.left(MAX_PRECEDENCE_PLUS_3)` so it outranks
  `member_expression` (MAX_PRECEDENCE_PLUS_2). Without that, the GLR
  conflict resolver preferred `member_expression(Base<Int>, Child2)`
  and choked on the trailing `<String>`. The no-arguments form keeps
  default precedence so `Base<Int>.Child` still parses as a
  `member_expression` (no AST shape change for that case).

  The previously-declared `[$.member_type, $._expression]` GLR conflict
  is now redundant (static precedence resolves the ambiguity) and was
  removed; tree-sitter flagged it as an unnecessary conflict.

Why this regressed silently
---------------------------
Neither failure is a tooling/grammar regression — both are new XTC
syntax patterns added to the manualTests corpus that the grammar
never had a test case for:

* generics.x:27 was added on 2026-05-06 by 0120712 ("Fix
  NameExpression code production for parameterized virtual child
  classes") — a compiler bugfix that needed a test exercising
  `Base<Int>.Child2<String>`.
* annos.x:141 was added on 2026-05-17 by 91f6d7d ("Fix a compiler
  exception (#463)") — a compiler bugfix that needed a test exercising
  a local `annotation … into …` declaration.

Both PRs only touched `manualTests/src/main/x/` and `javatools/`,
never `lang/`. The `dorny/paths-filter` gate in
`.github/workflows/commit.yml` skips the tree-sitter validation step
whenever no `lang/**` paths change, so the master CI run was green
even though both new test files would have failed grammar validation.
This PR (which touches `lang/vscode-extension/**`) is the first since
May 6 to trip the gate and run the validation, which is why both
failures surfaced together here.

The skip lists (parked.txt, intentional.txt) and the grammar template
itself were unchanged between PR #452 (May 1, last grammar work) and
the May 6 / May 17 corpus additions — git log confirms generics.x was
never in any skip list, so the parked.txt header comment "generics.x
parses cleanly now -- removed from this list" is incidentally
misleading; it refers to a draft state that never made it into git.

Verified: `:lang:tree-sitter:testTreeSitterParse` 881/881 (was 879/881),
`:lang:lsp-server:test -Plsp.adapter=treesitter` green,
`validateTreeSitterGrammar` no warnings.
@lagergren lagergren force-pushed the elvis/vscode-extension branch from 5bb10a0 to 046a9d5 Compare May 23, 2026 06:51
lagergren added 2 commits May 23, 2026 09:19
…re icon pipeline

Two related changes bundled together because the VS Code extension's user-
visible identity (name, language alias, command palette, settings page) had
drifted from the IntelliJ plugin's "Ecstasy" branding, and the icon pipeline
that previously placed icons under `lang/vscode-extension/icons/` was removed
in commit 96fdfcd without a replacement, leaving the extension unpackagable
from a clean checkout.

Branding (XTC -> Ecstasy in human-readable strings)
---------------------------------------------------
Mirrors the IntelliJ plugin.xml convention: "Ecstasy" for the language name
as exposed to humans, "XTC" retained only for short-form/abbreviation use,
internal identifiers, and the server's own product name ("XTC Language
Server" — same in both plugins).

User-facing now reads "Ecstasy":
* package.json displayName, description (mirrors plugin.xml description
  prose), primary language alias, configuration title, command palette
  titles, debugger label, configurationSnippets label.
* README marketplace install prose, command-palette table, language-mode
  troubleshooting note, project-structure comment for commands.ts.
* Source-level user-visible strings: command prompts, info-message project
  creation banner, default debug-config name, "Cannot find module" error,
  JRE download progress title, extension.ts file-header.
* References to the COMPILED module artifact use `.xtc` (e.g. task
  moduleName/debugger module descriptions: "The Ecstasy (.xtc) module to
  run/debug").

Internal stays `xtc`:
* npm package name, publisher, language id, TextMate scope, all command
  IDs and settings keys, task/debugger `type` field, on-disk filenames,
  status-bar abbreviations (`✓ XTC` etc.), terminal label hosting the
  `xtc` CLI, internal console.log lines, JVM-args comment.
* "XTC Language Server" / "XTC DAP server" names — these are the server
  components' product names and match IntelliJ plugin.xml's `<server
  name="XTC Language Server">`.

Unified search terms (cross-plugin)
-----------------------------------
package.json `keywords` is the only source-controlled search-term field
(JetBrains Marketplace indexes name+description). Aligned with what the
IntelliJ plugin's name+description already covers:
  ecstasy, ecstasy-language, xtc, xvm, xtclang, xdk

Icon pipeline restoration
-------------------------
The `copyIcon` Gradle task was removed in 96fdfcd ("Update README and
configuration files for XTC extension") and package.json's icon refs were
switched from the working `icons/xtc.svg` to non-existent `icons/xtc.png`
+ `icons/xtc-file.png` in the same commit. The PNGs were never checked in,
so `vsce package` has been broken from any clean checkout since May 21.
CI never noticed because nothing in commit.yml invokes
`:lang:vscode-extension:packageExtension`.

New approach: derive both icons from the existing repository logo at build
time, so the JPEG source of truth in `doc/logo/x.jpg` stays canonical and
no derived artifacts land in git (`icons/` is already gitignored).

* New `:lang:vscode-extension:generateIcons` task — runs
  `scripts/generate-icons.cjs` via the node-gradle NodeTask, using `sharp`
  to convert `doc/logo/x.jpg` to `icons/xtc.png` (256x256, marketplace)
  and `icons/xtc-file.png` (32x32, language file icon). Composite-root
  resolution via `XdkPropertiesService.compositeRootDirectory(projectDir)`,
  matching the existing `copyLicense` task's pattern.
* sharp added as a devDependency in package.json.
* generateIcons wired into `packageExtension.dependsOn` and
  `assemble.dependsOn`; outputs cleaned by the `clean` task.
* scripts/** added to .vscodeignore so the build helper does not get
  bundled into the .vsix.

Verified
--------
* `./gradlew :lang:vscode-extension:packageExtension -PincludeBuildLang=true
  -PincludeBuildAttachLang=true` succeeds; produces
  `xtc-language-0.4.4.vsix` (10.85 MB, 27 files), with `extension/icons/`
  containing both generated PNGs.
* Configuration-cache compatible (stores on first run, reuses on second).
…serialization, sharp

Five small dependency refreshes audited against today's latest stable
releases; all five compile, lint, test, and package green locally with
the full lang composite included
(-PincludeBuildLang=true -PincludeBuildAttachLang=true):

* tree-sitter-cli 0.26.8 -> 0.26.9 (2026-05-19 patch). jtreesitter is
  still at 0.26.0; major.minor parity for ABI compatibility is preserved
  per the comment in libs.versions.toml.
* intellij-platform-gradle-plugin 2.14.0 -> 2.16.0 (2026-05-01,
  two minor versions behind). :lang:intellij-plugin:buildPlugin succeeds
  with the bumped plugin.
* lsp4ij 0.19.3 -> 0.19.4 (2026-05-21 patch).
* kotlinx-serialization 1.10.0 -> 1.11.0 (2026-04-09 minor).
* sharp (devDependency in lang/vscode-extension/package.json):
  ^0.33.5 -> ^0.34.5. Just-introduced dep for the icon-generation
  Gradle task; starting on the latest stable line so future minor
  resolves stay current.

Versions intentionally NOT bumped (already on latest stable):
  Kotlin 2.3.21 (2.4.0 is RC), Node 22.12.0 (LTS-22 pin), LSP4J 1.0.0,
  Logback 1.5.32, SLF4J 2.0.18, ktlint 14.2.0, ktlint-engine 1.8.0,
  jtreesitter 0.26.0, node-gradle-plugin 7.1.0, intellij-ide 2026.1,
  intellij-junit4-compat 4.13.2 (legacy compat pin), apache-commons-
  compress 1.28.0, tukaani-xz 1.12, zig 0.15.2 (GH releases list 0.15.1
  as latest tagged, but ziglang.org serves the 0.15.2 tarball — HTTP
  200 confirmed).

Verified locally:
  :lang:dsl:check
  :lang:tree-sitter:check
  :lang:tree-sitter:testTreeSitterParse           (881 passed, 0 failed)
  :lang:lsp-server:check                          (includes :test)
  :lang:dap-server:check
  :lang:intellij-plugin:buildPlugin
  :lang:vscode-extension:build                    (.vsix packaged OK)
@ezekielelvis ezekielelvis merged commit 45e908d into master May 23, 2026
4 checks passed
@ezekielelvis ezekielelvis deleted the elvis/vscode-extension branch May 23, 2026 08:16
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.

3 participants