@@ -340,15 +340,72 @@ extract_side_effects <- function(pd) {
340340# ' @keywords internal
341341# ' @noRd
342342extract_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+ }
351375 }
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 )
352409}
353410
354411# graph_parser ----
0 commit comments