Skip to content

Commit 698f1a3

Browse files
committed
Fix recursion in function bodies
1 parent 9671164 commit 698f1a3

File tree

3 files changed

+284
-19
lines changed

3 files changed

+284
-19
lines changed

crates/ark/src/lsp/snapshots/ark__lsp__symbols__tests__symbol_call_methods.snap

Lines changed: 105 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: crates/ark/src/lsp/symbols.rs
3-
expression: "test_symbol(\"\n# section ----\nlist(\n foo = function() {\n 1\n }, # matched\n function() {\n 2\n }, # not matched\n bar = function() {\n 3\n }, # matched\n baz = (function() {\n 4\n }) # not matched\n)\n\")"
3+
expression: "test_symbol(\"\n# section ----\nlist(\n foo = function() {\n 1\n # nested section ----\n nested <- function() {}\n }, # matched\n function() {\n 2\n # `nested` is a symbol even if the unnamed method is not\n nested <- function () {\n }\n }, # not matched\n bar = function() {\n 3\n }, # matched\n baz = (function() {\n 4\n }) # not matched\n)\n\")"
44
---
55
[
66
DocumentSymbol {
@@ -15,7 +15,7 @@ expression: "test_symbol(\"\n# section ----\nlist(\n foo = function() {\n
1515
character: 0,
1616
},
1717
end: Position {
18-
line: 15,
18+
line: 20,
1919
character: 1,
2020
},
2121
},
@@ -25,7 +25,7 @@ expression: "test_symbol(\"\n# section ----\nlist(\n foo = function() {\n
2525
character: 0,
2626
},
2727
end: Position {
28-
line: 15,
28+
line: 20,
2929
character: 1,
3030
},
3131
},
@@ -45,7 +45,7 @@ expression: "test_symbol(\"\n# section ----\nlist(\n foo = function() {\n
4545
character: 10,
4646
},
4747
end: Position {
48-
line: 5,
48+
line: 7,
4949
character: 5,
5050
},
5151
},
@@ -55,7 +55,103 @@ expression: "test_symbol(\"\n# section ----\nlist(\n foo = function() {\n
5555
character: 10,
5656
},
5757
end: Position {
58-
line: 5,
58+
line: 7,
59+
character: 5,
60+
},
61+
},
62+
children: Some(
63+
[
64+
DocumentSymbol {
65+
name: "nested section",
66+
detail: None,
67+
kind: String,
68+
tags: None,
69+
deprecated: None,
70+
range: Range {
71+
start: Position {
72+
line: 5,
73+
character: 8,
74+
},
75+
end: Position {
76+
line: 6,
77+
character: 31,
78+
},
79+
},
80+
selection_range: Range {
81+
start: Position {
82+
line: 5,
83+
character: 8,
84+
},
85+
end: Position {
86+
line: 6,
87+
character: 31,
88+
},
89+
},
90+
children: Some(
91+
[
92+
DocumentSymbol {
93+
name: "nested",
94+
detail: Some(
95+
"function()",
96+
),
97+
kind: Function,
98+
tags: None,
99+
deprecated: None,
100+
range: Range {
101+
start: Position {
102+
line: 6,
103+
character: 8,
104+
},
105+
end: Position {
106+
line: 6,
107+
character: 31,
108+
},
109+
},
110+
selection_range: Range {
111+
start: Position {
112+
line: 6,
113+
character: 8,
114+
},
115+
end: Position {
116+
line: 6,
117+
character: 31,
118+
},
119+
},
120+
children: Some(
121+
[],
122+
),
123+
},
124+
],
125+
),
126+
},
127+
],
128+
),
129+
},
130+
DocumentSymbol {
131+
name: "nested",
132+
detail: Some(
133+
"function()",
134+
),
135+
kind: Function,
136+
tags: None,
137+
deprecated: None,
138+
range: Range {
139+
start: Position {
140+
line: 11,
141+
character: 8,
142+
},
143+
end: Position {
144+
line: 12,
145+
character: 5,
146+
},
147+
},
148+
selection_range: Range {
149+
start: Position {
150+
line: 11,
151+
character: 8,
152+
},
153+
end: Position {
154+
line: 12,
59155
character: 5,
60156
},
61157
},
@@ -73,21 +169,21 @@ expression: "test_symbol(\"\n# section ----\nlist(\n foo = function() {\n
73169
deprecated: None,
74170
range: Range {
75171
start: Position {
76-
line: 9,
172+
line: 14,
77173
character: 10,
78174
},
79175
end: Position {
80-
line: 11,
176+
line: 16,
81177
character: 5,
82178
},
83179
},
84180
selection_range: Range {
85181
start: Position {
86-
line: 9,
182+
line: 14,
87183
character: 10,
88184
},
89185
end: Position {
90-
line: 11,
186+
line: 16,
91187
character: 5,
92188
},
93189
},
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
---
2+
source: crates/ark/src/lsp/symbols.rs
3+
expression: "test_symbol(\"\n# section ----\nclass <- r6::r6class(\n 'class',\n public = list(\n initialize = function() 'initialize',\n foo = function() 'foo'\n ),\n private = list(\n bar = function() 'bar'\n )\n)\n\")"
4+
---
5+
[
6+
DocumentSymbol {
7+
name: "section",
8+
detail: None,
9+
kind: String,
10+
tags: None,
11+
deprecated: None,
12+
range: Range {
13+
start: Position {
14+
line: 1,
15+
character: 0,
16+
},
17+
end: Position {
18+
line: 11,
19+
character: 1,
20+
},
21+
},
22+
selection_range: Range {
23+
start: Position {
24+
line: 1,
25+
character: 0,
26+
},
27+
end: Position {
28+
line: 11,
29+
character: 1,
30+
},
31+
},
32+
children: Some(
33+
[
34+
DocumentSymbol {
35+
name: "class",
36+
detail: None,
37+
kind: Variable,
38+
tags: None,
39+
deprecated: None,
40+
range: Range {
41+
start: Position {
42+
line: 2,
43+
character: 0,
44+
},
45+
end: Position {
46+
line: 2,
47+
character: 5,
48+
},
49+
},
50+
selection_range: Range {
51+
start: Position {
52+
line: 2,
53+
character: 0,
54+
},
55+
end: Position {
56+
line: 2,
57+
character: 5,
58+
},
59+
},
60+
children: Some(
61+
[
62+
DocumentSymbol {
63+
name: "initialize",
64+
detail: Some(
65+
"function()",
66+
),
67+
kind: Method,
68+
tags: None,
69+
deprecated: None,
70+
range: Range {
71+
start: Position {
72+
line: 5,
73+
character: 17,
74+
},
75+
end: Position {
76+
line: 5,
77+
character: 40,
78+
},
79+
},
80+
selection_range: Range {
81+
start: Position {
82+
line: 5,
83+
character: 17,
84+
},
85+
end: Position {
86+
line: 5,
87+
character: 40,
88+
},
89+
},
90+
children: Some(
91+
[],
92+
),
93+
},
94+
DocumentSymbol {
95+
name: "foo",
96+
detail: Some(
97+
"function()",
98+
),
99+
kind: Method,
100+
tags: None,
101+
deprecated: None,
102+
range: Range {
103+
start: Position {
104+
line: 6,
105+
character: 10,
106+
},
107+
end: Position {
108+
line: 6,
109+
character: 26,
110+
},
111+
},
112+
selection_range: Range {
113+
start: Position {
114+
line: 6,
115+
character: 10,
116+
},
117+
end: Position {
118+
line: 6,
119+
character: 26,
120+
},
121+
},
122+
children: Some(
123+
[],
124+
),
125+
},
126+
DocumentSymbol {
127+
name: "bar",
128+
detail: Some(
129+
"function()",
130+
),
131+
kind: Method,
132+
tags: None,
133+
deprecated: None,
134+
range: Range {
135+
start: Position {
136+
line: 9,
137+
character: 10,
138+
},
139+
end: Position {
140+
line: 9,
141+
character: 26,
142+
},
143+
},
144+
selection_range: Range {
145+
start: Position {
146+
line: 9,
147+
character: 10,
148+
},
149+
end: Position {
150+
line: 9,
151+
character: 26,
152+
},
153+
},
154+
children: Some(
155+
[],
156+
),
157+
},
158+
],
159+
),
160+
},
161+
],
162+
),
163+
},
164+
]

crates/ark/src/lsp/symbols.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -304,17 +304,13 @@ fn collect_call_arguments(
304304
collect_symbols(&arg_value, contents, 0, symbols)?;
305305

306306
if arg_value.kind() == "function_definition" {
307-
// Functions are not collected by `collect_symbols()` so we deal
308-
// with them here by processing the function body to extract child
309-
// symbols. We do this even if it's not a "method", i.e. if it's not
310-
// named.
311-
let body = arg_value.child_by_field_name("body").into_result()?;
312-
let mut children = Vec::new();
313-
collect_symbols(&body, contents, 0, &mut children)?;
314-
315-
// If there is a name node, collect it as a method
316307
if let Some(arg_fun) = arg.child_by_field_name("name") {
308+
// If this is a named function, collect it as a method
317309
collect_method(&arg_fun, &arg_value, contents, symbols)?;
310+
} else {
311+
// Otherwise, just recurse into the function
312+
let body = arg_value.child_by_field_name("body").into_result()?;
313+
collect_symbols(&body, contents, 0, symbols)?;
318314
};
319315
}
320316
}
@@ -336,11 +332,15 @@ fn collect_method(
336332
let start = convert_point_to_position(contents, arg_value.start_position());
337333
let end = convert_point_to_position(contents, arg_value.end_position());
338334

335+
let body = arg_value.child_by_field_name("body").into_result()?;
336+
let mut children = vec![];
337+
collect_symbols(&body, contents, 0, &mut children)?;
338+
339339
let mut symbol = new_symbol_node(
340340
arg_name_str,
341341
SymbolKind::METHOD,
342342
Range { start, end },
343-
vec![],
343+
children,
344344
);
345345

346346
// Don't include whole function as detail as the body often doesn't
@@ -771,9 +771,14 @@ test_that('bar', {
771771
list(
772772
foo = function() {
773773
1
774+
# nested section ----
775+
nested <- function() {}
774776
}, # matched
775777
function() {
776778
2
779+
# `nested` is a symbol even if the unnamed method is not
780+
nested <- function () {
781+
}
777782
}, # not matched
778783
bar = function() {
779784
3

0 commit comments

Comments
 (0)