Skip to content

fix(lsp): walk to enabled nested workspaces#34654

Merged
littledivy merged 3 commits into
mainfrom
orch/divybot-390
Jun 2, 2026
Merged

fix(lsp): walk to enabled nested workspaces#34654
littledivy merged 3 commits into
mainfrom
orch/divybot-390

Conversation

@divybot

@divybot divybot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Closes denoland/divybot#390
Fixes #28681

Summary

This fixes LSP workspace preloading when a workspace root is disabled but a nested workspace folder is explicitly enabled.

How this fixes the issue

The bug happened because Inner::walk_workspace() asks Settings::path_enabled() before descending into each directory. With deno.enable disabled at the root and enabled only for a nested workspace, the walk would skip disabled ancestor directories like apps/ before it could ever reach the enabled folder, so the LSP never discovered that nested workspace's deno.json or source files.

This change keeps those ancestor directories walkable when they contain a separately enabled workspace folder, while preserving the disabled result for unrelated root files and sibling directories. That lets the preload walk reach the enabled nested workspace without re-enabling the rest of the disabled root.

Tests

  • config_path_enabled_for_nested_workspace_folder covers the Settings::path_enabled() behavior for disabled roots and enabled nested workspaces.
  • test_walk_workspace_reaches_enabled_nested_workspace verifies the actual workspace walk reaches the nested workspace files and excludes disabled siblings/root files.

@littledivy littledivy changed the title [denoland/deno#28681] deno.enable in vscode either results in bad typings, or performance issues that make it unusable fix(lsp): walk to enabled nested workspaces Jun 1, 2026
@littledivy
littledivy force-pushed the orch/divybot-390 branch 2 times, most recently from bd2a1a0 to 3e9533e Compare June 1, 2026 14:18
@littledivy

Copy link
Copy Markdown
Member

@divybot Update PR desc, how does this fix the issue?

@divybot

divybot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

Updated the PR description with a summary, the mechanism of the fix, and the regression tests covering it.

@littledivy

Copy link
Copy Markdown
Member

Have you looked at the discussion in the issue? Can you try to reproduce it

@divybot

divybot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

Yes. I read through #28681 and cloned the linked repro (aliak00/deno-monorepo). The concrete setup is:

  • multi-root workspace: shared, backend, web, and root
  • workspace-level deno.enable: false
  • backend folder has deno.enable: true
  • backend deno.json uses an import map where core/ points to ../../shared/ts/core/src/

I verified the command-line part matches the issue: from apps/backend, /usr/bin/deno check src/run.ts succeeds. The LSP bug this PR addresses is that workspace preload would stop at disabled ancestor dirs like apps/, so it would not reach apps/backend/deno.json in this multi-root disabled-root setup.

I pushed e65233b to make the regression tests mirror that repro shape more closely: shared, backend, web, and root workspace folders, only backend enabled, and backend importing core/ through an import map. Focused verification passed locally:

cargo test -p deno --lib nested_workspace --features rustls/ring
# 2 passed

@littledivy

Copy link
Copy Markdown
Member

Have you tried e2e using lsp? I wanna see perf numbers before and after

@divybot

divybot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

I ran an e2e LSP measurement against the linked repro (aliak00/deno-monorepo) with two locally built debug binaries:

  • before: 19da4cbe8 (parent of the fix)
  • after: e65233bcc (current PR head)

Method:

  • started deno lsp over stdio
  • initialized with the repro workspace folders: shared, backend, web, root
  • answered workspace/configuration with workspace-level/root/shared/web deno.enable: false, backend deno.enable: true, and backend import map
  • enabled deno.internalDebug and parsed LSP performance measures from stderr
  • opened apps/backend/src/run.ts with the issue's bad return-value edit
  • requested deno:/status.md and textDocument/diagnostic
  • one warm-up per binary, then 5 measured warm runs with the same DENO_DIR

Results, medians from 5 warm runs:

metric before after
initialize-to-ready wall time 60.95ms 373.43ms
status server docs 0 3
lsp.initialize 0.775ms 0.771ms
lsp.update_global_cache 0.470ms 0.449ms
lsp.update_cache 0.030ms 0.029ms
lsp.did_open 4.110ms 3.740ms
tsc.op.op_script_names 0.323ms 0.712ms
tsc.op.op_resolve total 108.323ms 90.884ms

Interpretation: before is faster to ready because it is wrong for this repro: it preloads zero server docs and never reaches the enabled backend workspace through the disabled root. After loads the expected backend workspace files (deno.json, import_map.json, src/run.ts) and still reaches ready in ~373ms median on a debug build. The per-open path is comparable/slightly better in this run (lsp.did_open 3.74ms after vs 4.11ms before).

Caveat: in this isolated e2e run the diagnostic request reports npm-install-related diagnostics for zod, so I used this primarily to verify LSP workspace discovery and preload/cache perf rather than the final semantic diagnostic shape.

@littledivy
littledivy merged commit 3b0cdf4 into main Jun 2, 2026
136 checks passed
@littledivy
littledivy deleted the orch/divybot-390 branch June 2, 2026 04:50
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.

deno.enable in vscode either results in bad typings, or performance issues that make it unusable

2 participants