Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 59 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@
"version": "0.2.0",
"configurations": [
{
"name": "Launch Client",
"type": "extensionHost",
"request": "launch",
"name": "Launch Client",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}/editors/vscode"],
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/editors/vscode/dist/*.js"],
"outFiles": ["${workspaceFolder}/editors/vscode/out/**/*.js"],
"env": {
"SERVER_PATH_DEV": "${workspaceRoot}/editors/vscode/target/debug/oxc_language_server",
"RUST_LOG": "debug"
}
},
"preLaunchTask": "build: extension+rust"
},
{
"type": "lldb",
Expand All @@ -31,6 +32,61 @@
}
// "args": ["--ARGS-TO-OXLINT"],
// "cwd": "PATH-TO-TEST-PROJECT"
},
{
"name": "Language Server (Socket)",
"type": "lldb",
"request": "launch",
"cargo": {
"args": ["build", "--package", "oxc_language_server"],
"filter": {
"name": "oxc_language_server",
"kind": "bin"
}
},
"env": {
"OXC_LS_LISTEN": "unix:/tmp/oxc_ls.sock",
"RUST_LOG": "debug"
},
"sourceLanguages": ["rust"],
"expressions": "native",
"stopOnEntry": false,
"presentation": {
"hidden": true,
"group": "",
"order": 1
}
},
{
"name": "Launch Client (External LS)",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}/editors/vscode"],
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/editors/vscode/out/**/*.js"],
"env": {
"OXC_LS_CONNECT": "unix:/tmp/oxc_ls.sock",
"RUST_LOG": "debug"
},
"presentation": {
"hidden": true,
"group": "",
"order": 1,
}
}
],
"compounds": [
{
"name": "Debug VS Code Extension and Oxc Language Server",
"configurations": ["Language Server (Socket)", "Launch Client (External LS)"],
"stopAll": true,
"preLaunchTask": "build: extension+rust",
"presentation": {
"hidden": false,
"group": "",
"order": 1
}
}
]
}
120 changes: 120 additions & 0 deletions .vscode/lldb_rust_init.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
"""LLDB Rust pretty-printer bootstrap for CodeLLDB.

Loads official Rust formatters (lldb_lookup + lldb_commands) without hardcoded toolchain paths.
Adds summaries for core collection types and adjusts string length. Safe to re-run.
"""
from __future__ import annotations
import os, sys, shutil, subprocess

def log(*parts: object) -> None:
print("[lldb_rust_init]", *parts)

# 1) Ensure ~/.cargo/bin on PATH so rustc is discoverable when launched via CodeLLDB.
home = os.environ.get("HOME", "")
if home:
cargo_bin = os.path.join(home, ".cargo", "bin")
path = os.environ.get("PATH", "")
parts = path.split(os.pathsep) if path else []
if cargo_bin not in parts:
# Prepend cargo_bin preserving existing PATH using the correct platform-specific separator.
os.environ["PATH"] = os.pathsep.join([cargo_bin] + parts)
log("PATH prepended with", cargo_bin)
else:
log("HOME unset; skipping PATH prepend")

# 2) Locate rustc & sysroot.
rustc = shutil.which("rustc")
if not rustc:
log("rustc NOT FOUND; aborting formatter init")
raise SystemExit
log("rustc ->", rustc)
try:
sysroot = subprocess.check_output([rustc, "--print", "sysroot"], text=True).strip()
except Exception as e: # noqa: BLE001
log("Failed to get sysroot:", e)
raise SystemExit
log("sysroot ->", sysroot)

etc_dir = os.path.join(sysroot, "lib", "rustlib", "etc")
if not os.path.isdir(etc_dir):
log("Missing etc dir:", etc_dir)
raise SystemExit
log("Loading Rust formatters from", etc_dir)

# 3) Import lldb_lookup & source lldb_commands via LLDB command API.
if etc_dir not in sys.path:
sys.path.append(etc_dir)
try:
import lldb_lookup # type: ignore
log("Imported lldb_lookup OK")
except Exception as e: # noqa: BLE001
log("Import lldb_lookup FAILED:", e)
raise SystemExit

# Acquire lldb debugger object from injected global 'lldb' (provided by CodeLLDB environment).
try:
import lldb # type: ignore
except Exception as e: # noqa: BLE001
log("Unable to import lldb module (unexpected):", e)
raise SystemExit

dbg = lldb.debugger

# Source the static commands file for additional summaries (matches rust-lldb behavior).
commands_path = os.path.join(etc_dir, "lldb_commands")
if os.path.isfile(commands_path):
dbg.HandleCommand(f"command source -s 0 {commands_path}")
log("Sourced", commands_path)
else:
log("Commands file not found:", commands_path)

# Enable Rust category & increase max string summary length.
dbg.HandleCommand("type category enable Rust")
dbg.HandleCommand("settings set target.max-string-summary-length 2000")

# Register Vec printers explicitly (defensive if commands file changes in future).
dbg.HandleCommand(
'type synthetic add -l lldb_lookup.synthetic_lookup -x "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust'
)
dbg.HandleCommand(
'type summary add -F lldb_lookup.summary_lookup -e -x -h "^(alloc::([a-z_]+::)+)Vec<.+>$" --category Rust'
)

# Provide a concise summary for URI types (lsp_types::Url / fluent_uri::Uri wrappers).
# These commonly contain an inner String we want to display directly.
# We attempt a regex that matches types ending with `::Uri` or `::Url` and which have a
# single field referencing alloc::string::String.
def uri_summary(val_obj): # noqa: D401
"""LLDB summary callback for various Uri/Url wrapper types.

Tries to locate an inner alloc::string::String and return its contents.
Falls back to existing lldb_lookup.summary_lookup if structure differs.
"""
try:
# Heuristics: search immediate children then recurse one level.
for child in val_obj.children:
ty = child.type.name or ""
if "alloc::string::String" in ty:
# Use the default Rust String summary by delegating to lldb_lookup.
import lldb_lookup # type: ignore
return lldb_lookup.summary_lookup(child)
# Recurse one level for wrappers like tuple struct or newtype.
for child in val_obj.children:
for gchild in child.children:
ty = gchild.type.name or ""
if "alloc::string::String" in ty:
import lldb_lookup # type: ignore
return lldb_lookup.summary_lookup(gchild)
except Exception as e: # noqa: BLE001
return f"<uri err: {e}>"
return "<uri>"

try:
dbg.HandleCommand(
'type summary add -e -x -F lldb_rust_init.uri_summary "^(.*(::)+)(Url|Uri)$" --category Rust'
)
log("Registered custom Url/Uri summary")
except Exception as e:
log("Failed to register custom Url/Uri summary:", e)

log("Rust formatter initialization complete")
20 changes: 20 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Fix for CodeLLDB v1.11.0+ not showing Rust Vec contents in debugger
//
// Problem: CodeLLDB v1.11.0+ stopped bundling Rust pretty printers and expects
// them to load automatically from the Rust toolchain, but this often fails.
// Symptoms: Vec<T> shows only "buf" and "len" instead of expandable elements
//
// Solution: Manually load the Rust LLDB formatters using preRunCommands
// - Uses dynamic path resolution via `rustc --print sysroot` for cross-platform compatibility
// - Works on Linux, Windows, and macOS without hardcoded paths
//
// Reference: https://github.com/vadimcn/codelldb/issues/1166
"lldb.launch.initCommands": [
// Import Rust LLDB formatters and custom URI summaries
"script import sys; sys.path.append('.vscode'); import lldb_rust_init"
],
"lldb.showDisassembly": "auto",
"lldb.dereferencePointers": true,
"lldb.consoleMode": "commands",
}
28 changes: 28 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@
"$tsc"
]
},
{
"label": "extension: compile",
"type": "npm",
"script": "compile",
"options": {
"cwd": "${workspaceFolder}/editors/vscode"
},
"group": "build",
"presentation": {
"panel": "dedicated",
"reveal": "silent",
"clear": true
},
"problemMatcher": [
"$tsc"
]
},
{
"type": "shell",
"command": "cd ./editors/vscode && npm run watch",
Expand All @@ -71,6 +88,17 @@
"panel": "dedicated",
"reveal": "never"
}
},
{
"label": "build: extension+rust",
"dependsOn": [
"extension: compile",
"rust: cargo test --no-run"
],
"problemMatcher": [],
"group": {
"kind": "build"
}
}
]
}
Loading