Skip to content

Commit 6587cb4

Browse files
committed
bye bye ass_cond
1 parent 13fec70 commit 6587cb4

File tree

2 files changed

+61
-8
lines changed

2 files changed

+61
-8
lines changed

R/utils-get_code_dependency.R

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ extract_occurrence <- function(pd) {
274274
# What occurs in a function body is not tracked.
275275
x <- pd[!is_in_function(pd), ]
276276
sym_cond <- which(x$token %in% c("SPECIAL", "SYMBOL", "SYMBOL_FUNCTION_CALL"))
277+
sym_fc_cond <- which(x$token == "SYMBOL_FUNCTION_CALL")
277278

278279
if (length(sym_cond) == 0) {
279280
return(character(0L))
@@ -287,28 +288,30 @@ extract_occurrence <- function(pd) {
287288
sym_cond <- setdiff(sym_cond, which(x$id %in% after_dollar))
288289
}
289290

290-
ass_cond <- grep("ASSIGN", x$token)
291-
if (!length(ass_cond)) {
291+
assign_cond <- grep("ASSIGN", x$token)
292+
if (!length(assign_cond)) {
292293
return(c("<-", unique(x[sym_cond, "text"])))
293294
}
294295

295-
sym_cond <- sym_cond[sym_cond > ass_cond] # NOTE 1
296+
# For cases like 'eval(expression(c <- b + 2))' removes 'eval(expression('.
297+
sym_cond <- setdiff(
298+
sym_cond,
299+
sym_cond[sym_cond < min(assign_cond) & sym_cond %in% sym_fc_cond]
300+
)
301+
296302
# If there was an assignment operation detect direction of it.
297-
if (unique(x$text[ass_cond]) == "->") { # NOTE 2
303+
if (unique(x$text[assign_cond]) == "->") { # What if there are 2 assignments: e.g. a <- b -> c.
298304
sym_cond <- rev(sym_cond)
299305
}
300306

301-
after <- match(min(x$id[ass_cond]), sort(x$id[c(min(ass_cond), sym_cond)])) - 1
307+
after <- match(min(x$id[assign_cond]), sort(x$id[c(min(assign_cond), sym_cond)])) - 1
302308
ans <- append(x[sym_cond, "text"], "<-", after = max(1, after))
303309
roll <- in_parenthesis(pd)
304310
if (length(roll)) {
305311
c(setdiff(ans, roll), roll)
306312
} else {
307313
ans
308314
}
309-
310-
### NOTE 2: What if there are 2 assignments: e.g. a <- b -> c.
311-
### NOTE 1: For cases like 'eval(expression(b <- b + 2))' removes 'eval(expression('.
312315
}
313316

314317
#' Extract side effects

tests/testthat/test-qenv_get_code.R

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,56 @@ testthat::test_that("detects occurrence of a function definition with a @linksto
596596
pasten(code[1:2])
597597
)
598598
})
599+
600+
601+
# for loop --------------------------------------------------------------------------------------------------------
602+
603+
testthat::test_that("objects in for loop are extracted if passed as one character", {
604+
605+
code <- "
606+
some_other_dataset <- mtcars
607+
original_dataset <- iris[, 1:4]
608+
count <- 1
609+
for (x in colnames(original_dataset)) {
610+
original_dataset[, x] <- original_dataset[, x] * 2
611+
count <- count + 1
612+
}
613+
output <- rlang::list2(x = original_dataset)
614+
"
615+
q <- eval_code(qenv(), code)
616+
testthat::expect_identical(
617+
get_code(q, names = "output"),
618+
gsub("\n some_other_dataset <- mtcars\n", "", code, fixed = TRUE)
619+
)
620+
621+
})
622+
623+
testthat::test_that("objects in for loop are extracted if passed as separate calls", {
624+
q <- within(qenv(), {
625+
a <- 1
626+
b <- 2
627+
}) |> within({
628+
for (x in c(1, 2)) {
629+
b <- a
630+
b <- b + a + 1
631+
b + 3 -> b
632+
}
633+
})
634+
635+
testthat::expect_setequal(
636+
strsplit(get_code(q, names = "b"), "\n")[[1]],
637+
c(
638+
"a <- 1",
639+
"b <- 2",
640+
"for (x in c(1, 2)) {",
641+
" b <- a",
642+
" b <- b + a + 1",
643+
" b <- b + 3", #ORDER IS CHANGED IN HERE, but we can live with it
644+
"}"
645+
)
646+
)
647+
})
648+
599649
# $ ---------------------------------------------------------------------------------------------------------------
600650

601651
testthat::test_that("understands $ usage and do not treat rhs of $ as objects (only lhs)", {

0 commit comments

Comments
 (0)