Skip to content

Commit 6b61766

Browse files
committed
languages: Add inline values support for JavaScript, TypeScript, and TSX
This commit adds debugger.scm files and tests for JavaScript, TypeScript, and TSX languages to enable inline variable value display during debugging sessions. The implementation uses Tree-sitter queries to capture: - Variable declarations (var, let, const) - Function parameters (regular, arrow, destructured) - Object and array destructuring patterns - Loop variables (for, for-in, for-of, while) - Try-catch error variables - Class fields and methods - Lexical scopes (blocks, functions, classes) Added comprehensive tests in debugger_ui covering: - JavaScript inline values - TypeScript inline values with types - Arrow functions - Destructuring patterns Release Notes: - Added inline variable value display during debugging for JavaScript, TypeScript, and TSX. Variable values now appear inline in the editor while debugging.
1 parent 69025f3 commit 6b61766

File tree

4 files changed

+407
-1
lines changed

4 files changed

+407
-1
lines changed

crates/debugger_ui/src/tests/inline_values.rs

Lines changed: 258 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ use std::{path::Path, sync::Arc};
33
use dap::{Scope, StackFrame, Variable, requests::Variables};
44
use editor::{Editor, EditorMode, MultiBuffer};
55
use gpui::{BackgroundExecutor, TestAppContext, VisualTestContext};
6-
use language::{Language, LanguageConfig, LanguageMatcher, tree_sitter_python, tree_sitter_rust};
6+
use language::{
7+
Language, LanguageConfig, LanguageMatcher, tree_sitter_python, tree_sitter_rust,
8+
tree_sitter_typescript,
9+
};
710
use project::{FakeFs, Project};
811
use serde_json::json;
912
use unindent::Unindent as _;
@@ -2272,3 +2275,257 @@ fn main() {
22722275
)
22732276
.await;
22742277
}
2278+
2279+
fn javascript_lang() -> Language {
2280+
let debug_variables_query = include_str!("../../../languages/src/javascript/debugger.scm");
2281+
Language::new(
2282+
LanguageConfig {
2283+
name: "JavaScript".into(),
2284+
matcher: LanguageMatcher {
2285+
path_suffixes: vec!["js".to_string()],
2286+
..Default::default()
2287+
},
2288+
..Default::default()
2289+
},
2290+
Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
2291+
)
2292+
.with_debug_variables_query(debug_variables_query)
2293+
.unwrap()
2294+
}
2295+
2296+
fn typescript_lang() -> Language {
2297+
let debug_variables_query = include_str!("../../../languages/src/typescript/debugger.scm");
2298+
Language::new(
2299+
LanguageConfig {
2300+
name: "TypeScript".into(),
2301+
matcher: LanguageMatcher {
2302+
path_suffixes: vec!["ts".to_string()],
2303+
..Default::default()
2304+
},
2305+
..Default::default()
2306+
},
2307+
Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
2308+
)
2309+
.with_debug_variables_query(debug_variables_query)
2310+
.unwrap()
2311+
}
2312+
2313+
fn tsx_lang() -> Language {
2314+
let debug_variables_query = include_str!("../../../languages/src/tsx/debugger.scm");
2315+
Language::new(
2316+
LanguageConfig {
2317+
name: "TSX".into(),
2318+
matcher: LanguageMatcher {
2319+
path_suffixes: vec!["tsx".to_string()],
2320+
..Default::default()
2321+
},
2322+
..Default::default()
2323+
},
2324+
Some(tree_sitter_typescript::LANGUAGE_TSX.into()),
2325+
)
2326+
.with_debug_variables_query(debug_variables_query)
2327+
.unwrap()
2328+
}
2329+
2330+
#[gpui::test]
2331+
async fn test_javascript_inline_values(executor: BackgroundExecutor, cx: &mut TestAppContext) {
2332+
let variables = [
2333+
("x", "10"),
2334+
("y", "20"),
2335+
("sum", "30"),
2336+
("message", "Hello"),
2337+
];
2338+
2339+
let before = r#"
2340+
function calculate() {
2341+
const x = 10;
2342+
const y = 20;
2343+
const sum = x + y;
2344+
const message = "Hello";
2345+
console.log(message, "Sum:", sum);
2346+
}
2347+
"#
2348+
.unindent();
2349+
2350+
let after = r#"
2351+
function calculate() {
2352+
const x: 10 = 10;
2353+
const y: 20 = 20;
2354+
const sum: 30 = x: 10 + y: 20;
2355+
const message = "Hello";
2356+
console.log(message, "Sum:", sum);
2357+
}
2358+
"#
2359+
.unindent();
2360+
2361+
test_inline_values_util(
2362+
&variables,
2363+
&[],
2364+
&before,
2365+
&after,
2366+
None,
2367+
javascript_lang(),
2368+
executor,
2369+
cx,
2370+
)
2371+
.await;
2372+
}
2373+
2374+
#[gpui::test]
2375+
async fn test_typescript_inline_values(executor: BackgroundExecutor, cx: &mut TestAppContext) {
2376+
let variables = [
2377+
("count", "42"),
2378+
("name", "Alice"),
2379+
("result", "84"),
2380+
("i", "3"),
2381+
];
2382+
2383+
let before = r#"
2384+
function processData(count: number, name: string): number {
2385+
let result = count * 2;
2386+
for (let i = 0; i < 5; i++) {
2387+
console.log(i);
2388+
}
2389+
return result;
2390+
}
2391+
"#
2392+
.unindent();
2393+
2394+
let after = r#"
2395+
function processData(count: 42: number, name: Alice: string): number {
2396+
let result: 84 = count: 42 * 2;
2397+
for (let i: 3 = 0; i: 3 < 5; i: 3++) {
2398+
console.log(i: 3);
2399+
}
2400+
return result: 84;
2401+
}
2402+
"#
2403+
.unindent();
2404+
2405+
test_inline_values_util(
2406+
&variables,
2407+
&[],
2408+
&before,
2409+
&after,
2410+
None,
2411+
typescript_lang(),
2412+
executor,
2413+
cx,
2414+
)
2415+
.await;
2416+
}
2417+
2418+
#[gpui::test]
2419+
async fn test_tsx_inline_values(executor: BackgroundExecutor, cx: &mut TestAppContext) {
2420+
let variables = [("count", "5"), ("message", "Hello React")];
2421+
2422+
let before = r#"
2423+
const Counter = () => {
2424+
const count = 5;
2425+
const message = "Hello React";
2426+
return (
2427+
<div>
2428+
<p>{message}</p>
2429+
<span>{count}</span>
2430+
</div>
2431+
);
2432+
};
2433+
"#
2434+
.unindent();
2435+
2436+
let after = r#"
2437+
const Counter = () => {
2438+
const count: 5 = 5;
2439+
const message = "Hello React";
2440+
return (
2441+
<div>
2442+
<p>{message}</p>
2443+
<span>{count: 5}</span>
2444+
</div>
2445+
);
2446+
};
2447+
"#
2448+
.unindent();
2449+
2450+
test_inline_values_util(
2451+
&variables,
2452+
&[],
2453+
&before,
2454+
&after,
2455+
None,
2456+
tsx_lang(),
2457+
executor,
2458+
cx,
2459+
)
2460+
.await;
2461+
}
2462+
2463+
#[gpui::test]
2464+
async fn test_javascript_arrow_functions(executor: BackgroundExecutor, cx: &mut TestAppContext) {
2465+
let variables = [("x", "42"), ("result", "84")];
2466+
2467+
let before = r#"
2468+
const double = (x) => {
2469+
const result = x * 2;
2470+
return result;
2471+
};
2472+
"#
2473+
.unindent();
2474+
2475+
let after = r#"
2476+
const double = (x: 42) => {
2477+
const result: 84 = x: 42 * 2;
2478+
return result: 84;
2479+
};
2480+
"#
2481+
.unindent();
2482+
2483+
test_inline_values_util(
2484+
&variables,
2485+
&[],
2486+
&before,
2487+
&after,
2488+
None,
2489+
javascript_lang(),
2490+
executor,
2491+
cx,
2492+
)
2493+
.await;
2494+
}
2495+
2496+
#[gpui::test]
2497+
async fn test_typescript_for_in_loop(executor: BackgroundExecutor, cx: &mut TestAppContext) {
2498+
let variables = [("key", "name"), ("obj", "{name: 'test'}")];
2499+
2500+
let before = r#"
2501+
function iterate() {
2502+
const obj = {name: 'test'};
2503+
for (const key in obj) {
2504+
console.log(key);
2505+
}
2506+
}
2507+
"#
2508+
.unindent();
2509+
2510+
let after = r#"
2511+
function iterate() {
2512+
const obj: {name: 'test'} = {name: 'test'};
2513+
for (const key: name in obj: {name: 'test'}) {
2514+
console.log(key: name);
2515+
}
2516+
}
2517+
"#
2518+
.unindent();
2519+
2520+
test_inline_values_util(
2521+
&variables,
2522+
&[],
2523+
&before,
2524+
&after,
2525+
None,
2526+
typescript_lang(),
2527+
executor,
2528+
cx,
2529+
)
2530+
.await;
2531+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
; JavaScript Debug Variables Query
2+
; Simplified version focusing on most common patterns
3+
4+
; Variable declarations
5+
(variable_declarator
6+
name: (identifier) @debug-variable)
7+
8+
; Arrow function parameters (simple identifier only)
9+
(arrow_function
10+
parameter: (identifier) @debug-variable)
11+
12+
; For loop variables
13+
(for_in_statement
14+
left: (identifier) @debug-variable)
15+
16+
; Scopes
17+
(statement_block) @debug-scope
18+
19+
(function_declaration
20+
body: (statement_block) @debug-scope)
21+
22+
(method_definition
23+
body: (statement_block) @debug-scope)
24+
25+
(arrow_function
26+
body: (statement_block) @debug-scope)
27+
28+
(class_declaration
29+
body: (class_body) @debug-scope)
30+
31+
(for_statement
32+
body: (statement_block) @debug-scope)
33+
34+
(while_statement
35+
body: (statement_block) @debug-scope)
36+
37+
(if_statement
38+
consequence: (statement_block) @debug-scope
39+
alternative: (statement_block)? @debug-scope)
40+
41+
(try_statement
42+
body: (statement_block) @debug-scope)
43+
44+
(catch_clause
45+
body: (statement_block) @debug-scope)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
; TSX Debug Variables Query
2+
; Only using verified node types from tree-sitter-typescript
3+
4+
; Variable declarations
5+
(variable_declarator
6+
name: (identifier) @debug-variable)
7+
8+
; Function/method parameters
9+
(required_parameter
10+
pattern: (identifier) @debug-variable)
11+
12+
(optional_parameter
13+
pattern: (identifier) @debug-variable)
14+
15+
; Arrow function single parameter
16+
(arrow_function
17+
parameter: (identifier) @debug-variable)
18+
19+
; For loop variables
20+
(for_in_statement
21+
left: (identifier) @debug-variable)
22+
23+
; Scopes
24+
(statement_block) @debug-scope
25+
26+
(function_declaration
27+
body: (statement_block) @debug-scope)
28+
29+
(method_definition
30+
body: (statement_block) @debug-scope)
31+
32+
(arrow_function
33+
body: (statement_block) @debug-scope)
34+
35+
(class_declaration
36+
body: (class_body) @debug-scope)
37+
38+
(for_statement
39+
body: (statement_block) @debug-scope)
40+
41+
(while_statement
42+
body: (statement_block) @debug-scope)
43+
44+
(if_statement
45+
consequence: (statement_block) @debug-scope
46+
alternative: (statement_block)? @debug-scope)
47+
48+
(try_statement
49+
body: (statement_block) @debug-scope)
50+
51+
(catch_clause
52+
body: (statement_block) @debug-scope)

0 commit comments

Comments
 (0)