Skip to content

Commit cba4960

Browse files
committed
Refactor indexers to collect in a vector
1 parent 8f8f293 commit cba4960

File tree

2 files changed

+88
-92
lines changed

2 files changed

+88
-92
lines changed

crates/ark/src/lsp/indexer.rs

Lines changed: 84 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -198,127 +198,119 @@ fn index_document(document: &Document, path: &Path) {
198198

199199
let root = ast.root_node();
200200
let mut cursor = root.walk();
201+
let mut entries = Vec::new();
202+
201203
for node in root.children(&mut cursor) {
202-
if let Err(err) = match index_node(path, contents, &node) {
203-
Ok(Some(entry)) => insert(path, entry),
204-
Ok(None) => Ok(()),
205-
Err(err) => Err(err),
206-
} {
204+
if let Err(err) = index_node(path, contents, &node, &mut entries) {
207205
lsp::log_error!("Can't index document: {err:?}");
208206
}
209207
}
210-
}
211-
212-
fn index_node(path: &Path, contents: &Rope, node: &Node) -> anyhow::Result<Option<IndexEntry>> {
213-
if let Ok(Some(entry)) = index_function(path, contents, node) {
214-
return Ok(Some(entry));
215-
}
216-
217-
// Should be after function indexing as this is a more general case
218-
if let Ok(Some(entry)) = index_variable(path, contents, node) {
219-
return Ok(Some(entry));
220-
}
221208

222-
if let Ok(Some(entry)) = index_comment(path, contents, node) {
223-
return Ok(Some(entry));
209+
for entry in entries {
210+
if let Err(err) = insert(path, entry) {
211+
lsp::log_error!("Can't insert index entry: {err:?}");
212+
}
224213
}
225-
226-
Ok(None)
227214
}
228215

229-
fn index_function(
230-
_path: &Path,
216+
fn index_node(
217+
path: &Path,
231218
contents: &Rope,
232219
node: &Node,
233-
) -> anyhow::Result<Option<IndexEntry>> {
234-
// Check for assignment.
235-
matches!(
236-
node.node_type(),
237-
NodeType::BinaryOperator(BinaryOperatorType::LeftAssignment) |
238-
NodeType::BinaryOperator(BinaryOperatorType::EqualsAssignment)
239-
)
240-
.into_result()?;
241-
242-
// Check for identifier on left-hand side.
243-
let lhs = node.child_by_field_name("lhs").into_result()?;
244-
lhs.is_identifier_or_string().into_result()?;
245-
246-
// Check for a function definition on the right-hand side.
247-
let rhs = node.child_by_field_name("rhs").into_result()?;
248-
rhs.is_function_definition().into_result()?;
249-
250-
let name = contents.node_slice(&lhs)?.to_string();
251-
let mut arguments = Vec::new();
252-
253-
// Get the parameters node.
254-
let parameters = rhs.child_by_field_name("parameters").into_result()?;
255-
256-
// Iterate through each, and get the names.
257-
let mut cursor = parameters.walk();
258-
for child in parameters.children(&mut cursor) {
259-
let name = unwrap!(child.child_by_field_name("name"), None => continue);
260-
if name.is_identifier() {
261-
let name = contents.node_slice(&name)?.to_string();
262-
arguments.push(name);
263-
}
264-
}
265-
266-
let start = convert_point_to_position(contents, lhs.start_position());
267-
let end = convert_point_to_position(contents, lhs.end_position());
268-
269-
Ok(Some(IndexEntry {
270-
key: name.clone(),
271-
range: Range { start, end },
272-
data: IndexEntryData::Function {
273-
name: name.clone(),
274-
arguments,
275-
},
276-
}))
220+
entries: &mut Vec<IndexEntry>,
221+
) -> anyhow::Result<()> {
222+
index_assignment(path, contents, node, entries)?;
223+
index_comment(path, contents, node, entries)?;
224+
Ok(())
277225
}
278226

279-
fn index_variable(
227+
fn index_assignment(
280228
_path: &Path,
281229
contents: &Rope,
282230
node: &Node,
283-
) -> anyhow::Result<Option<IndexEntry>> {
231+
entries: &mut Vec<IndexEntry>,
232+
) -> anyhow::Result<()> {
284233
if !matches!(
285234
node.node_type(),
286235
NodeType::BinaryOperator(BinaryOperatorType::LeftAssignment) |
287236
NodeType::BinaryOperator(BinaryOperatorType::EqualsAssignment)
288237
) {
289-
return Ok(None);
238+
return Ok(());
290239
}
291240

292-
let Some(lhs) = node.child_by_field_name("lhs") else {
293-
return Ok(None);
241+
let lhs = match node.child_by_field_name("lhs") {
242+
Some(lhs) => lhs,
243+
None => return Ok(()),
294244
};
295245

296246
let lhs_text = contents.node_slice(&lhs)?.to_string();
297247

298-
// Super hacky but let's wait until the typed API to do better
248+
// The method matching is super hacky but let's wait until the typed API to
249+
// do better
299250
if !lhs_text.starts_with("method(") && !lhs.is_identifier_or_string() {
300-
return Ok(None);
251+
return Ok(());
301252
}
302253

303-
let start = convert_point_to_position(contents, lhs.start_position());
304-
let end = convert_point_to_position(contents, lhs.end_position());
254+
let Some(rhs) = node.child_by_field_name("rhs") else {
255+
return Ok(());
256+
};
305257

306-
Ok(Some(IndexEntry {
307-
key: lhs_text.clone(),
308-
range: Range { start, end },
309-
data: IndexEntryData::Variable { name: lhs_text },
310-
}))
258+
if rhs.is_function_definition() {
259+
// If RHS is a function definition, emit a function symbol
260+
let mut arguments = Vec::new();
261+
if let Some(parameters) = rhs.child_by_field_name("parameters") {
262+
let mut cursor = parameters.walk();
263+
for child in parameters.children(&mut cursor) {
264+
let name = unwrap!(child.child_by_field_name("name"), None => continue);
265+
if name.is_identifier() {
266+
let name = contents.node_slice(&name)?.to_string();
267+
arguments.push(name);
268+
}
269+
}
270+
}
271+
272+
let start = convert_point_to_position(contents, lhs.start_position());
273+
let end = convert_point_to_position(contents, lhs.end_position());
274+
275+
entries.push(IndexEntry {
276+
key: lhs_text.clone(),
277+
range: Range { start, end },
278+
data: IndexEntryData::Function {
279+
name: lhs_text,
280+
arguments,
281+
},
282+
});
283+
} else {
284+
// Otherwise, emit variable
285+
let start = convert_point_to_position(contents, lhs.start_position());
286+
let end = convert_point_to_position(contents, lhs.end_position());
287+
entries.push(IndexEntry {
288+
key: lhs_text.clone(),
289+
range: Range { start, end },
290+
data: IndexEntryData::Variable { name: lhs_text },
291+
});
292+
}
293+
294+
Ok(())
311295
}
312296

313-
fn index_comment(_path: &Path, contents: &Rope, node: &Node) -> anyhow::Result<Option<IndexEntry>> {
297+
fn index_comment(
298+
_path: &Path,
299+
contents: &Rope,
300+
node: &Node,
301+
entries: &mut Vec<IndexEntry>,
302+
) -> anyhow::Result<()> {
314303
// check for comment
315-
node.is_comment().into_result()?;
304+
if !node.is_comment() {
305+
return Ok(());
306+
}
316307

317308
// see if it looks like a section
318309
let comment = contents.node_slice(node)?.to_string();
319-
let matches = RE_COMMENT_SECTION
320-
.captures(comment.as_str())
321-
.into_result()?;
310+
let matches = match RE_COMMENT_SECTION.captures(comment.as_str()) {
311+
Some(m) => m,
312+
None => return Ok(()),
313+
};
322314

323315
let level = matches.get(1).into_result()?;
324316
let title = matches.get(2).into_result()?;
@@ -328,18 +320,21 @@ fn index_comment(_path: &Path, contents: &Rope, node: &Node) -> anyhow::Result<O
328320

329321
// skip things that look like knitr output
330322
if title.starts_with("----") {
331-
return Ok(None);
323+
return Ok(());
332324
}
333325

334326
let start = convert_point_to_position(contents, node.start_position());
335327
let end = convert_point_to_position(contents, node.end_position());
336328

337-
Ok(Some(IndexEntry {
329+
entries.push(IndexEntry {
338330
key: title.clone(),
339331
range: Range::new(start, end),
340332
data: IndexEntryData::Section { level, title },
341-
}))
333+
});
334+
335+
Ok(())
342336
}
337+
343338
#[cfg(test)]
344339
mod tests {
345340
use std::path::PathBuf;
@@ -358,9 +353,7 @@ mod tests {
358353

359354
let mut entries = vec![];
360355
for node in root.children(&mut cursor) {
361-
if let Ok(Some(entry)) = index_node(&path, &doc.contents, &node) {
362-
entries.push(entry);
363-
}
356+
let _ = index_node(&path, &doc.contents, &node, &mut entries);
364357
}
365358
assert_debug_snapshot!(entries);
366359
};

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,11 @@ expression: entries
4747
character: 22,
4848
},
4949
},
50-
data: Variable {
50+
data: Function {
5151
name: "method(generic, Class)",
52+
arguments: [
53+
"arg",
54+
],
5255
},
5356
},
5457
]

0 commit comments

Comments
 (0)