Skip to content

Commit 004364f

Browse files
committed
- single evaluate::evaluate
- mask environment for qenv - remove semicolon from the code
1 parent ec49b8d commit 004364f

File tree

2 files changed

+42
-45
lines changed

2 files changed

+42
-45
lines changed

R/qenv-class.R

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,19 @@ setMethod(
3131
"initialize",
3232
"qenv",
3333
function(.Object, .xData, code = list(), ...) { # nolint: object_name.
34+
mask_env <- new.env(parent = parent.env(.GlobalEnv))
35+
mask_env$library <- function(...) {
36+
x <- library(...)
37+
if (!identical(parent.env(mask_env), parent.env(.GlobalEnv))) {
38+
parent.env(mask_env) <- parent.env(.GlobalEnv)
39+
}
40+
invisible(x)
41+
}
3442
new_xdata <- if (rlang::is_missing(.xData)) {
35-
new.env(parent = parent.env(.GlobalEnv))
43+
new.env(parent = mask_env)
3644
} else {
3745
checkmate::assert_environment(.xData)
38-
rlang::env_clone(.xData, parent = parent.env(.GlobalEnv))
46+
rlang::env_clone(.xData, parent = mask_env)
3947
}
4048
lockEnvironment(new_xdata, bindings = TRUE)
4149

R/qenv-eval_code.R

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -44,56 +44,45 @@ setMethod("eval_code", signature = c(object = "qenv.error"), function(object, co
4444
if (identical(trimws(code), "") || length(code) == 0) {
4545
return(object)
4646
}
47+
code <- paste(split_code(code), collapse = "\n")
48+
49+
object@.xData <- rlang::env_clone(object@.xData, parent = parent.env(object@.xData))
4750
parsed_code <- parse(text = code, keep.source = TRUE)
48-
object@.xData <- rlang::env_clone(object@.xData, parent = parent.env(.GlobalEnv))
49-
if (length(parsed_code) == 0) {
50-
# empty code, or just comments
51-
attr(code, "dependency") <- extract_dependency(parsed_code) # in case comment contains @linksto tag
52-
object@code <- c(object@code, stats::setNames(list(code), sample.int(.Machine$integer.max, size = 1)))
53-
return(object)
54-
}
55-
code_split <- split_code(paste(code, collapse = "\n"))
5651

57-
for (i in seq_along(code_split)) {
58-
current_code <- code_split[[i]]
59-
current_call <- parse(text = current_code, keep.source = TRUE)
60-
x <- evaluate::evaluate(
61-
current_code,
62-
envir = object@.xData,
63-
stop_on_error = 1,
64-
output_handler = evaluate::new_output_handler(value = identity)
65-
)
52+
out <- evaluate::evaluate(
53+
code,
54+
envir = object@.xData,
55+
stop_on_error = 1,
56+
output_handler = evaluate::new_output_handler(value = identity)
57+
)
6658

67-
e <- Filter(function(e) inherits(e, "error"), x)
68-
if (length(e)) {
69-
return(
70-
errorCondition(
71-
message = sprintf(
72-
"%s \n when evaluating qenv code:\n%s",
73-
cli::ansi_strip(conditionMessage(e[[1]])),
74-
current_code
75-
),
76-
class = c("qenv.error", "try-error", "simpleError"),
77-
trace = unlist(c(object@code, list(current_code)))
59+
new_code <- list()
60+
for (this in out) {
61+
if (inherits(this, "source")) {
62+
this_code <- gsub("\n$", "", this$src)
63+
attr(this_code, "dependency") <- extract_dependency(parse(text = this_code))
64+
new_code <- c(new_code, stats::setNames(list(this_code), sample.int(.Machine$integer.max, size = 1)))
65+
} else {
66+
last_code <- new_code[[length(new_code)]]
67+
if (inherits(this, "error")) {
68+
return(
69+
errorCondition(
70+
message = sprintf(
71+
"%s \n when evaluating qenv code:\n%s",
72+
cli::ansi_strip(conditionMessage(this)),
73+
last_code
74+
),
75+
class = c("qenv.error", "try-error", "simpleError"),
76+
trace = unlist(c(object@code, list(new_code)))
77+
)
7878
)
79-
)
79+
}
80+
attr(last_code, "outputs") <- c(attr(last_code, "outputs"), list(this))
81+
new_code[[length(new_code)]] <- last_code
8082
}
81-
if (!identical(parent.env(object@.xData), parent.env(.GlobalEnv))) {
82-
# needed to make sure that @.xData is always a sibling of .GlobalEnv
83-
# could be changed when any new package is added to search path (through library or require call)
84-
parent.env(object@.xData) <- parent.env(.GlobalEnv)
85-
}
86-
87-
attributes(current_code) <- Filter(
88-
length,
89-
list(
90-
dependency = extract_dependency(current_call),
91-
outputs = x[-1]
92-
)
93-
)
94-
object@code <- c(object@code, stats::setNames(list(current_code), sample.int(.Machine$integer.max, size = 1)))
9583
}
9684

85+
object@code <- c(object@code, new_code)
9786
lockEnvironment(object@.xData, bindings = TRUE)
9887
object
9988
}

0 commit comments

Comments
 (0)