@@ -340,15 +340,72 @@ extract_side_effects <- function(pd) {
340
340
# ' @keywords internal
341
341
# ' @noRd
342
342
extract_dependency <- function (parsed_code ) {
343
- pd <- normalize_pd(utils :: getParseData(parsed_code ))
344
- reordered_pd <- extract_calls(pd )
345
- if (length(reordered_pd ) > 0 ) {
346
- # extract_calls is needed to reorder the pd so that assignment operator comes before symbol names
347
- # extract_calls is needed also to substitute assignment operators into specific format with fix_arrows
348
- # extract_calls is needed to omit empty calls that contain only one token `"';'"`
349
- # This cleaning is needed as extract_occurrence assumes arrows are fixed, and order is different than in original pd
350
- c(extract_side_effects(reordered_pd [[1 ]]), extract_occurrence(reordered_pd [[1 ]]))
343
+ full_pd <- normalize_pd(utils :: getParseData(parsed_code ))
344
+ reordered_full_pd <- extract_calls(full_pd )
345
+
346
+ # Early return on empty code
347
+ if (length(reordered_full_pd ) == 0L ) {
348
+ return (NULL )
349
+ }
350
+
351
+ if (length(parsed_code ) == 0L ) {
352
+ return (extract_side_effects(reordered_full_pd [[1 ]]))
353
+ }
354
+ expr_ix <- lapply(parsed_code [[1 ]], class ) == " {"
355
+
356
+ # Build queue of expressions to parse individually
357
+ queue <- list ()
358
+ parsed_code_list <- if (all(! expr_ix )) {
359
+ list (parsed_code )
360
+ } else {
361
+ queue <- as.list(parsed_code [[1 ]][expr_ix ])
362
+ new_list <- parsed_code [[1 ]]
363
+ new_list [expr_ix ] <- NULL
364
+ list (parse(text = as.expression(new_list ), keep.source = TRUE ))
365
+ }
366
+
367
+ while (length(queue ) > 0 ) {
368
+ current <- queue [[1 ]]
369
+ queue <- queue [- 1 ]
370
+ if (identical(current [[1L ]], as.name(" {" ))) {
371
+ queue <- append(queue , as.list(current )[- 1L ])
372
+ } else {
373
+ parsed_code_list [[length(parsed_code_list ) + 1 ]] <- parse(text = as.expression(current ), keep.source = TRUE )
374
+ }
351
375
}
376
+
377
+ parsed_occurences <- lapply(
378
+ parsed_code_list ,
379
+ function (parsed_code ) {
380
+ pd <- normalize_pd(utils :: getParseData(parsed_code ))
381
+ reordered_pd <- extract_calls(pd )
382
+ if (length(reordered_pd ) > 0 ) {
383
+ # extract_calls is needed to reorder the pd so that assignment operator comes before symbol names
384
+ # extract_calls is needed also to substitute assignment operators into specific format with fix_arrows
385
+ # extract_calls is needed to omit empty calls that contain only one token `"';'"`
386
+ # This cleaning is needed as extract_occurrence assumes arrows are fixed, and order is different
387
+ # than in original pd
388
+ extract_occurrence(reordered_pd [[1 ]])
389
+ }
390
+ }
391
+ )
392
+
393
+ # Merge results together
394
+ result <- Reduce(
395
+ function (u , v ) {
396
+ ix <- if (" <-" %in% v ) min(which(v == " <-" )) else 0
397
+ u $ left_side <- c(u $ left_side , v [seq_len(max(0 , ix - 1 ))])
398
+ u $ right_side <- c(
399
+ u $ right_side ,
400
+ if (ix == length(v )) character (0L ) else v [seq(ix + 1 , max(ix + 1 , length(v )))]
401
+ )
402
+ u
403
+ },
404
+ init = list (left_side = character (0L ), right_side = character (0L )),
405
+ x = parsed_occurences
406
+ )
407
+
408
+ c(extract_side_effects(reordered_full_pd [[1 ]]), result $ left_side , " <-" , result $ right_side )
352
409
}
353
410
354
411
# graph_parser ----
0 commit comments