Skip to content

Commit 9907d59

Browse files
committed
feat: add workspace-wide linting support
- Introduced `workspaceMode` option in the configuration to enable linting across all files in the workspace. - Updated `Options` struct to include `supported_extensions` for file type filtering. - Enhanced `lint_workspace` method to handle multiple file types based on supported extensions. - Implemented source file watchers for workspace mode to monitor changes in relevant files. - Updated VSCode extension to support new configuration options and handle workspace mode changes. - Added logging capabilities to forward log messages to the LSP client for better visibility. - Refactored `TsGoLintState` to support batch linting of multiple paths and return diagnostics grouped by file. - Improved error handling and diagnostics reporting in the linter service.
1 parent 43d74e4 commit 9907d59

File tree

24 files changed

+1416
-170
lines changed

24 files changed

+1416
-170
lines changed

.vscode/launch.json

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,18 @@
33
"version": "0.2.0",
44
"configurations": [
55
{
6+
"name": "Launch Client",
67
"type": "extensionHost",
78
"request": "launch",
8-
"name": "Launch Client",
99
"runtimeExecutable": "${execPath}",
1010
"args": ["--extensionDevelopmentPath=${workspaceFolder}/editors/vscode"],
1111
"sourceMaps": true,
12-
"outFiles": ["${workspaceFolder}/editors/vscode/dist/*.js"],
12+
"outFiles": ["${workspaceFolder}/editors/vscode/out/**/*.js"],
1313
"env": {
1414
"SERVER_PATH_DEV": "${workspaceRoot}/editors/vscode/target/debug/oxc_language_server",
1515
"RUST_LOG": "debug"
16-
}
16+
},
17+
"preLaunchTask": "build: extension+rust"
1718
},
1819
{
1920
"type": "lldb",
@@ -31,6 +32,61 @@
3132
}
3233
// "args": ["--ARGS-TO-OXLINT"],
3334
// "cwd": "PATH-TO-TEST-PROJECT"
35+
},
36+
{
37+
"name": "Language Server (Socket)",
38+
"type": "lldb",
39+
"request": "launch",
40+
"cargo": {
41+
"args": ["build", "--package", "oxc_language_server"],
42+
"filter": {
43+
"name": "oxc_language_server",
44+
"kind": "bin"
45+
}
46+
},
47+
"env": {
48+
"OXC_LS_LISTEN": "unix:/tmp/oxc_ls.sock",
49+
"RUST_LOG": "debug"
50+
},
51+
"sourceLanguages": ["rust"],
52+
"expressions": "native",
53+
"stopOnEntry": false,
54+
"presentation": {
55+
"hidden": true,
56+
"group": "",
57+
"order": 1
58+
}
59+
},
60+
{
61+
"name": "Launch Client (External LS)",
62+
"type": "extensionHost",
63+
"request": "launch",
64+
"runtimeExecutable": "${execPath}",
65+
"args": ["--extensionDevelopmentPath=${workspaceFolder}/editors/vscode"],
66+
"sourceMaps": true,
67+
"outFiles": ["${workspaceFolder}/editors/vscode/out/**/*.js"],
68+
"env": {
69+
"OXC_LS_CONNECT": "unix:/tmp/oxc_ls.sock",
70+
"RUST_LOG": "debug"
71+
},
72+
"presentation": {
73+
"hidden": true,
74+
"group": "",
75+
"order": 1,
76+
}
77+
}
78+
],
79+
"compounds": [
80+
{
81+
"name": "Debug VS Code Extension and Oxc Language Server",
82+
"configurations": ["Language Server (Socket)", "Launch Client (External LS)"],
83+
"stopAll": true,
84+
"preLaunchTask": "build: extension+rust",
85+
"presentation": {
86+
"hidden": false,
87+
"group": "",
88+
"order": 1
89+
}
3490
}
3591
]
3692
}

.vscode/lldb_rust_init.py

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
"""LLDB Rust pretty-printer bootstrap for CodeLLDB.
2+
3+
Loads official Rust formatters (lldb_lookup + lldb_commands) without hardcoded toolchain paths.
4+
Adds summaries for core collection types and adjusts string length. Safe to re-run.
5+
"""
6+
from __future__ import annotations
7+
import os, sys, shutil, subprocess
8+
9+
def log(*parts: object) -> None:
10+
print("[lldb_rust_init]", *parts)
11+
12+
# 1) Ensure ~/.cargo/bin on PATH so rustc is discoverable when launched via CodeLLDB.
13+
home = os.environ.get("HOME", "")
14+
if home:
15+
cargo_bin = os.path.join(home, ".cargo", "bin")
16+
path = os.environ.get("PATH", "")
17+
if cargo_bin not in path.split(":"):
18+
os.environ["PATH"] = cargo_bin + (":" + path if path else "")
19+
log("PATH prepended with", cargo_bin)
20+
else:
21+
log("HOME unset; skipping PATH prepend")
22+
23+
# 2) Locate rustc & sysroot.
24+
rustc = shutil.which("rustc")
25+
if not rustc:
26+
log("rustc NOT FOUND; aborting formatter init")
27+
raise SystemExit
28+
log("rustc ->", rustc)
29+
try:
30+
sysroot = subprocess.check_output([rustc, "--print", "sysroot"], text=True).strip()
31+
except Exception as e: # noqa: BLE001
32+
log("Failed to get sysroot:", e)
33+
raise SystemExit
34+
log("sysroot ->", sysroot)
35+
36+
etc_dir = os.path.join(sysroot, "lib", "rustlib", "etc")
37+
if not os.path.isdir(etc_dir):
38+
log("Missing etc dir:", etc_dir)
39+
raise SystemExit
40+
log("Loading Rust formatters from", etc_dir)
41+
42+
# 3) Import lldb_lookup & source lldb_commands via LLDB command API.
43+
if etc_dir not in sys.path:
44+
sys.path.append(etc_dir)
45+
try:
46+
import lldb_lookup # type: ignore
47+
log("Imported lldb_lookup OK")
48+
except Exception as e: # noqa: BLE001
49+
log("Import lldb_lookup FAILED:", e)
50+
raise SystemExit
51+
52+
# Acquire lldb debugger object from injected global 'lldb' (provided by CodeLLDB environment).
53+
try:
54+
import lldb # type: ignore
55+
except Exception as e: # noqa: BLE001
56+
log("Unable to import lldb module (unexpected):", e)
57+
raise SystemExit
58+
59+
dbg = lldb.debugger
60+
61+
# Source the static commands file for additional summaries (matches rust-lldb behavior).
62+
commands_path = os.path.join(etc_dir, "lldb_commands")
63+
if os.path.isfile(commands_path):
64+
dbg.HandleCommand(f"command source -s 0 {commands_path}")
65+
log("Sourced", commands_path)
66+
else:
67+
log("Commands file not found:", commands_path)
68+
69+
# Enable Rust category & increase max string summary length.
70+
dbg.HandleCommand("type category enable Rust")
71+
dbg.HandleCommand("settings set target.max-string-summary-length 2000")
72+
73+
# Register Vec printers explicitly (defensive if commands file changes in future).
74+
dbg.HandleCommand(
75+
'type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust'
76+
)
77+
dbg.HandleCommand(
78+
'type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust'
79+
)
80+
81+
# Provide a concise summary for URI types (lsp_types::Url / fluent_uri::Uri wrappers).
82+
# These commonly contain an inner String we want to display directly.
83+
# We attempt a regex that matches types ending with `::Uri` or `::Url` and which have a
84+
# single field referencing alloc::string::String.
85+
def uri_summary(val_obj): # noqa: D401
86+
"""LLDB summary callback for various Uri/Url wrapper types.
87+
88+
Tries to locate an inner alloc::string::String and return its contents.
89+
Falls back to existing lldb_lookup.summary_lookup if structure differs.
90+
"""
91+
try:
92+
# Heuristics: search immediate children then recurse one level.
93+
for child in val_obj.children:
94+
ty = child.type.name or ""
95+
if "alloc::string::String" in ty:
96+
# Use the default Rust String summary by delegating to lldb_lookup.
97+
import lldb_lookup # type: ignore
98+
return lldb_lookup.summary_lookup(child)
99+
# Recurse one level for wrappers like tuple struct or newtype.
100+
for child in val_obj.children:
101+
for gchild in child.children:
102+
ty = gchild.type.name or ""
103+
if "alloc::string::String" in ty:
104+
import lldb_lookup # type: ignore
105+
return lldb_lookup.summary_lookup(gchild)
106+
except Exception as e: # noqa: BLE001
107+
return f"<uri err: {e}>"
108+
return "<uri>"
109+
110+
try:
111+
dbg.HandleCommand(
112+
'type summary add -e -x -F lldb_rust_init.uri_summary "^(.*(::)+)(Url|Uri)$" --category Rust'
113+
)
114+
log("Registered custom Url/Uri summary")
115+
except Exception as e: # noqa: BLE001
116+
log("Failed to register custom Url/Uri summary:", e)
117+
118+
log("Rust formatter initialization complete")

.vscode/settings.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
// Fix for CodeLLDB v1.11.0+ not showing Rust Vec contents in debugger
3+
//
4+
// Problem: CodeLLDB v1.11.0+ stopped bundling Rust pretty printers and expects
5+
// them to load automatically from the Rust toolchain, but this often fails.
6+
// Symptoms: Vec<T> shows only "buf" and "len" instead of expandable elements
7+
//
8+
// Solution: Manually load the Rust LLDB formatters using preRunCommands
9+
// - Uses dynamic path resolution via `rustc --print sysroot` for cross-platform compatibility
10+
// - Works on Linux, Windows, and macOS without hardcoded paths
11+
//
12+
// Reference: https://github.com/vadimcn/codelldb/issues/1166
13+
"lldb.launch.initCommands": [
14+
// Import external module so its functions (uri_summary) are addressable by name.
15+
"script import os, sys; mod_path = os.path.join(os.getcwd(), '.vscode'); print('[codelldb:init] adding', mod_path); sys.path.append(mod_path) if mod_path not in sys.path else None; import lldb_rust_init"
16+
],
17+
}

.vscode/tasks.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,23 @@
5858
"$tsc"
5959
]
6060
},
61+
{
62+
"label": "extension: compile",
63+
"type": "npm",
64+
"script": "compile",
65+
"options": {
66+
"cwd": "${workspaceFolder}/editors/vscode"
67+
},
68+
"group": "build",
69+
"presentation": {
70+
"panel": "dedicated",
71+
"reveal": "silent",
72+
"clear": true
73+
},
74+
"problemMatcher": [
75+
"$tsc"
76+
]
77+
},
6178
{
6279
"type": "shell",
6380
"command": "cd ./editors/vscode && npm run watch",
@@ -71,6 +88,17 @@
7188
"panel": "dedicated",
7289
"reveal": "never"
7390
}
91+
},
92+
{
93+
"label": "build: extension+rust",
94+
"dependsOn": [
95+
"extension: compile",
96+
"rust: cargo test --no-run"
97+
],
98+
"problemMatcher": [],
99+
"group": {
100+
"kind": "build"
101+
}
74102
}
75103
]
76104
}

0 commit comments

Comments
 (0)