Skip to content

Commit c7aef45

Browse files
committed
Emit test_that() calls as symbols
1 parent 74dbe94 commit c7aef45

File tree

2 files changed

+253
-0
lines changed

2 files changed

+253
-0
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
---
2+
source: crates/ark/src/lsp/symbols.rs
3+
expression: "test_symbol(\"\ntest_that_not('foo', {\n 1\n})\n\n# title ----\n\ntest_that('foo', {\n # title1 ----\n 1\n # title2 ----\n foo <- function() {\n 2\n }\n})\n\")"
4+
---
5+
[
6+
DocumentSymbol {
7+
name: "title",
8+
detail: None,
9+
kind: String,
10+
tags: None,
11+
deprecated: None,
12+
range: Range {
13+
start: Position {
14+
line: 5,
15+
character: 0,
16+
},
17+
end: Position {
18+
line: 14,
19+
character: 2,
20+
},
21+
},
22+
selection_range: Range {
23+
start: Position {
24+
line: 5,
25+
character: 0,
26+
},
27+
end: Position {
28+
line: 14,
29+
character: 2,
30+
},
31+
},
32+
children: Some(
33+
[
34+
DocumentSymbol {
35+
name: "Test: foo",
36+
detail: None,
37+
kind: Function,
38+
tags: None,
39+
deprecated: None,
40+
range: Range {
41+
start: Position {
42+
line: 7,
43+
character: 0,
44+
},
45+
end: Position {
46+
line: 14,
47+
character: 2,
48+
},
49+
},
50+
selection_range: Range {
51+
start: Position {
52+
line: 7,
53+
character: 0,
54+
},
55+
end: Position {
56+
line: 14,
57+
character: 2,
58+
},
59+
},
60+
children: Some(
61+
[
62+
DocumentSymbol {
63+
name: "title1",
64+
detail: None,
65+
kind: String,
66+
tags: None,
67+
deprecated: None,
68+
range: Range {
69+
start: Position {
70+
line: 8,
71+
character: 2,
72+
},
73+
end: Position {
74+
line: 9,
75+
character: 3,
76+
},
77+
},
78+
selection_range: Range {
79+
start: Position {
80+
line: 8,
81+
character: 2,
82+
},
83+
end: Position {
84+
line: 9,
85+
character: 3,
86+
},
87+
},
88+
children: Some(
89+
[],
90+
),
91+
},
92+
DocumentSymbol {
93+
name: "title2",
94+
detail: None,
95+
kind: String,
96+
tags: None,
97+
deprecated: None,
98+
range: Range {
99+
start: Position {
100+
line: 10,
101+
character: 2,
102+
},
103+
end: Position {
104+
line: 13,
105+
character: 3,
106+
},
107+
},
108+
selection_range: Range {
109+
start: Position {
110+
line: 10,
111+
character: 2,
112+
},
113+
end: Position {
114+
line: 13,
115+
character: 3,
116+
},
117+
},
118+
children: Some(
119+
[
120+
DocumentSymbol {
121+
name: "foo",
122+
detail: Some(
123+
"function()",
124+
),
125+
kind: Function,
126+
tags: None,
127+
deprecated: None,
128+
range: Range {
129+
start: Position {
130+
line: 11,
131+
character: 2,
132+
},
133+
end: Position {
134+
line: 13,
135+
character: 3,
136+
},
137+
},
138+
selection_range: Range {
139+
start: Position {
140+
line: 11,
141+
character: 2,
142+
},
143+
end: Position {
144+
line: 13,
145+
character: 3,
146+
},
147+
},
148+
children: Some(
149+
[],
150+
),
151+
},
152+
],
153+
),
154+
},
155+
],
156+
),
157+
},
158+
],
159+
),
160+
},
161+
]

crates/ark/src/lsp/symbols.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ fn collect_symbols(
156156
collect_sections(node, contents, current_level, symbols)?;
157157
},
158158

159+
NodeType::Call => {
160+
collect_call(node, contents, symbols)?;
161+
},
162+
159163
NodeType::BinaryOperator(BinaryOperatorType::LeftAssignment) |
160164
NodeType::BinaryOperator(BinaryOperatorType::EqualsAssignment) => {
161165
collect_assignment(node, contents, symbols)?;
@@ -253,6 +257,72 @@ fn collect_sections(
253257
Ok(())
254258
}
255259

260+
fn collect_call(
261+
node: &Node,
262+
contents: &Rope,
263+
symbols: &mut Vec<DocumentSymbol>,
264+
) -> anyhow::Result<()> {
265+
let Some(callee) = node.child_by_field_name("function") else {
266+
return Ok(());
267+
};
268+
if !callee.is_identifier() {
269+
return Ok(());
270+
}
271+
272+
let fun_symbol = contents.node_slice(&callee)?.to_string();
273+
274+
match fun_symbol.as_str() {
275+
"test_that" => collect_call_test_that(node, contents, symbols)?,
276+
_ => {},
277+
}
278+
279+
Ok(())
280+
}
281+
282+
// https://github.com/posit-dev/positron/issues/1428
283+
fn collect_call_test_that(
284+
node: &Node,
285+
contents: &Rope,
286+
symbols: &mut Vec<DocumentSymbol>,
287+
) -> anyhow::Result<()> {
288+
let Some(arguments) = node.child_by_field_name("arguments") else {
289+
return Ok(());
290+
};
291+
292+
// We don't do any argument matching and just consider the first argument if
293+
// a string. First skip over `(`.
294+
let Some(first_argument) = arguments.child(1).and_then(|n| n.child(0)) else {
295+
return Ok(());
296+
};
297+
if !first_argument.is_string() {
298+
return Ok(());
299+
}
300+
301+
let Some(string) = first_argument.child_by_field_name("content") else {
302+
return Ok(());
303+
};
304+
305+
// Recurse in arguments. We could skip the first one if we wanted.
306+
let mut children = Vec::new();
307+
let mut cursor = arguments.walk();
308+
for child in arguments.children_by_field_name("argument", &mut cursor) {
309+
if let Some(value) = child.child_by_field_name("value") {
310+
collect_symbols(&value, contents, 0, &mut children)?;
311+
}
312+
}
313+
314+
let name = contents.node_slice(&string)?.to_string();
315+
let name = format!("Test: {name}");
316+
317+
let start = convert_point_to_position(contents, node.start_position());
318+
let end = convert_point_to_position(contents, node.end_position());
319+
320+
let symbol = new_symbol_node(name, SymbolKind::FUNCTION, Range { start, end }, children);
321+
symbols.push(symbol);
322+
323+
Ok(())
324+
}
325+
256326
fn collect_assignment(
257327
node: &Node,
258328
contents: &Rope,
@@ -587,4 +657,26 @@ z <- 3",
587657
assert_eq!(section_b.range.start.line, 4);
588658
assert_eq!(section_b.range.end.line, 5); // End of function body
589659
}
660+
661+
#[test]
662+
fn test_symbol_call_test_that() {
663+
insta::assert_debug_snapshot!(test_symbol(
664+
"
665+
test_that_not('foo', {
666+
1
667+
})
668+
669+
# title ----
670+
671+
test_that('foo', {
672+
# title1 ----
673+
1
674+
# title2 ----
675+
foo <- function() {
676+
2
677+
}
678+
})
679+
"
680+
));
681+
}
590682
}

0 commit comments

Comments
 (0)