@@ -198,127 +198,119 @@ fn index_document(document: &Document, path: &Path) {
198
198
199
199
let root = ast. root_node ( ) ;
200
200
let mut cursor = root. walk ( ) ;
201
+ let mut entries = Vec :: new ( ) ;
202
+
201
203
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) {
207
205
lsp:: log_error!( "Can't index document: {err:?}" ) ;
208
206
}
209
207
}
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
- }
221
208
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
+ }
224
213
}
225
-
226
- Ok ( None )
227
214
}
228
215
229
- fn index_function (
230
- _path : & Path ,
216
+ fn index_node (
217
+ path : & Path ,
231
218
contents : & Rope ,
232
219
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 ( ( ) )
277
225
}
278
226
279
- fn index_variable (
227
+ fn index_assignment (
280
228
_path : & Path ,
281
229
contents : & Rope ,
282
230
node : & Node ,
283
- ) -> anyhow:: Result < Option < IndexEntry > > {
231
+ entries : & mut Vec < IndexEntry > ,
232
+ ) -> anyhow:: Result < ( ) > {
284
233
if !matches ! (
285
234
node. node_type( ) ,
286
235
NodeType :: BinaryOperator ( BinaryOperatorType :: LeftAssignment ) |
287
236
NodeType :: BinaryOperator ( BinaryOperatorType :: EqualsAssignment )
288
237
) {
289
- return Ok ( None ) ;
238
+ return Ok ( ( ) ) ;
290
239
}
291
240
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 ( ( ) ) ,
294
244
} ;
295
245
296
246
let lhs_text = contents. node_slice ( & lhs) ?. to_string ( ) ;
297
247
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
299
250
if !lhs_text. starts_with ( "method(" ) && !lhs. is_identifier_or_string ( ) {
300
- return Ok ( None ) ;
251
+ return Ok ( ( ) ) ;
301
252
}
302
253
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
+ } ;
305
257
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 ( ( ) )
311
295
}
312
296
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 < ( ) > {
314
303
// check for comment
315
- node. is_comment ( ) . into_result ( ) ?;
304
+ if !node. is_comment ( ) {
305
+ return Ok ( ( ) ) ;
306
+ }
316
307
317
308
// see if it looks like a section
318
309
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
+ } ;
322
314
323
315
let level = matches. get ( 1 ) . into_result ( ) ?;
324
316
let title = matches. get ( 2 ) . into_result ( ) ?;
@@ -328,18 +320,21 @@ fn index_comment(_path: &Path, contents: &Rope, node: &Node) -> anyhow::Result<O
328
320
329
321
// skip things that look like knitr output
330
322
if title. starts_with ( "----" ) {
331
- return Ok ( None ) ;
323
+ return Ok ( ( ) ) ;
332
324
}
333
325
334
326
let start = convert_point_to_position ( contents, node. start_position ( ) ) ;
335
327
let end = convert_point_to_position ( contents, node. end_position ( ) ) ;
336
328
337
- Ok ( Some ( IndexEntry {
329
+ entries . push ( IndexEntry {
338
330
key : title. clone ( ) ,
339
331
range : Range :: new ( start, end) ,
340
332
data : IndexEntryData :: Section { level, title } ,
341
- } ) )
333
+ } ) ;
334
+
335
+ Ok ( ( ) )
342
336
}
337
+
343
338
#[ cfg( test) ]
344
339
mod tests {
345
340
use std:: path:: PathBuf ;
@@ -358,9 +353,7 @@ mod tests {
358
353
359
354
let mut entries = vec![ ] ;
360
355
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) ;
364
357
}
365
358
assert_debug_snapshot!( entries) ;
366
359
} ;
0 commit comments