Skip to content

Commit 03ad377

Browse files
m7prgogonzochlebowagithub-actions[bot]Aleksander Chlebowski
authored
#133 code parser alternative (#146)
Fixes #133 Alternative to #139 --------- Signed-off-by: Marcin <[email protected]> Co-authored-by: go_gonzo <[email protected]> Co-authored-by: Aleksander Chlebowski <[email protected]> Co-authored-by: Dawid Kałędkowski <[email protected]> Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Aleksander Chlebowski <[email protected]>
1 parent 1aa0ba2 commit 03ad377

29 files changed

+1112
-194
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,4 @@ tmp.*
2727
vignettes/*.R
2828
vignettes/*.html
2929
vignettes/*.md
30+
tests/testthat/Rplots.pdf

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,5 @@ Collate:
6161
'qenv-show.R'
6262
'qenv-within.R'
6363
'teal.code-package.R'
64+
'utils-code_dependency.R'
6465
'utils.R'

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# teal.code 0.4.1.9001
22

3+
* The `@code` field in the `qenv` class now holds `character`, not `expression`.
4+
35
# teal.code 0.4.1
46

57
### Miscellaneous

R/qenv-class.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#' Reproducible class with environment and code.
44
#' @name qenv-class
55
#' @rdname qenv-class
6-
#' @slot code (`expression`) to reproduce the environment
6+
#' @slot code (`character`) representing code necessary to reproduce the environment
77
#' @slot env (`environment`) environment which content was generated by the evaluation
88
#' of the `code` slot.
99
#' @slot id (`integer`) random identifier of the code element to make sure uniqueness
@@ -13,9 +13,9 @@
1313
#' @keywords internal
1414
setClass(
1515
"qenv",
16-
slots = c(env = "environment", code = "expression", id = "integer", warnings = "character", messages = "character"),
16+
slots = c(env = "environment", code = "character", id = "integer", warnings = "character", messages = "character"),
1717
prototype = list(
18-
env = new.env(parent = parent.env(.GlobalEnv)), code = expression(), id = integer(0),
18+
env = new.env(parent = parent.env(.GlobalEnv)), code = character(0), id = integer(0),
1919
warnings = character(0), messages = character(0)
2020
)
2121
)

R/qenv-constructor.R

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,21 @@
1010
#'
1111
#' @examples
1212
#' new_qenv(env = list2env(list(a = 1)), code = quote(a <- 1))
13-
#' new_qenv(env = list2env(list(a = 1)), code = parse(text = "a <- 1"))
13+
#' new_qenv(env = list2env(list(a = 1)), code = parse(text = "a <- 1", keep.source = TRUE))
1414
#' new_qenv(env = list2env(list(a = 1)), code = "a <- 1")
1515
#'
1616
#' @return `qenv` object.
1717
#'
1818
#' @export
19-
setGeneric("new_qenv", function(env = new.env(parent = parent.env(.GlobalEnv)), code = expression()) standardGeneric("new_qenv")) # nolint
19+
setGeneric("new_qenv", function(env = new.env(parent = parent.env(.GlobalEnv)), code = character()) standardGeneric("new_qenv")) # nolint
2020

2121
#' @rdname new_qenv
2222
#' @export
2323
setMethod(
2424
"new_qenv",
2525
signature = c(env = "environment", code = "expression"),
2626
function(env, code) {
27-
new_env <- rlang::env_clone(env, parent = parent.env(.GlobalEnv))
28-
lockEnvironment(new_env, bindings = TRUE)
29-
id <- sample.int(.Machine$integer.max, size = length(code))
30-
methods::new(
31-
"qenv",
32-
env = new_env, code = code, warnings = rep("", length(code)), messages = rep("", length(code)), id = id
33-
)
27+
new_qenv(env, format_expression(code))
3428
}
3529
)
3630

@@ -40,7 +34,14 @@ setMethod(
4034
"new_qenv",
4135
signature = c(env = "environment", code = "character"),
4236
function(env, code) {
43-
new_qenv(env, code = parse(text = code, keep.source = FALSE))
37+
new_env <- rlang::env_clone(env, parent = parent.env(.GlobalEnv))
38+
lockEnvironment(new_env, bindings = TRUE)
39+
if (length(code) > 0) code <- paste(code, collapse = "\n")
40+
id <- sample.int(.Machine$integer.max, size = length(code))
41+
methods::new(
42+
"qenv",
43+
env = new_env, code = code, warnings = rep("", length(code)), messages = rep("", length(code)), id = id
44+
)
4445
}
4546
)
4647

@@ -50,8 +51,7 @@ setMethod(
5051
"new_qenv",
5152
signature = c(env = "environment", code = "language"),
5253
function(env, code) {
53-
code_expr <- as.expression(code)
54-
new_qenv(env = env, code = code_expr)
54+
new_qenv(env = env, code = format_expression(code))
5555
}
5656
)
5757

R/qenv-eval_code.R

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,31 +21,33 @@ setGeneric("eval_code", function(object, code) standardGeneric("eval_code"))
2121

2222
#' @rdname eval_code
2323
#' @export
24-
setMethod("eval_code", signature = c("qenv", "expression"), function(object, code) {
25-
id <- sample.int(.Machine$integer.max, size = length(code))
24+
setMethod("eval_code", signature = c("qenv", "character"), function(object, code) {
25+
id <- sample.int(.Machine$integer.max, size = 1)
2626

2727
object@id <- c(object@id, id)
2828
object@env <- rlang::env_clone(object@env, parent = parent.env(.GlobalEnv))
29+
code <- paste(code, collapse = "\n")
2930
object@code <- c(object@code, code)
3031

3132
current_warnings <- ""
3233
current_messages <- ""
3334

34-
for (code_line in code) {
35-
# Using withCallingHandlers to capture ALL warnings and messages.
36-
# Using tryCatch to capture the FIRST error and abort further evaluation.
35+
parsed_code <- parse(text = code, keep.source = TRUE)
36+
for (single_call in parsed_code) {
37+
# Using withCallingHandlers to capture warnings and messages.
38+
# Using tryCatch to capture the error and abort further evaluation.
3739
x <- withCallingHandlers(
3840
tryCatch(
3941
{
40-
eval(code_line, envir = object@env)
42+
eval(single_call, envir = object@env)
4143
NULL
4244
},
4345
error = function(e) {
4446
errorCondition(
4547
message = sprintf(
4648
"%s \n when evaluating qenv code:\n%s",
4749
.ansi_strip(conditionMessage(e)),
48-
paste(format_expression(code), collapse = "\n")
50+
deparse1(single_call)
4951
),
5052
class = c("qenv.error", "try-error", "simpleError"),
5153
trace = object@code
@@ -61,28 +63,30 @@ setMethod("eval_code", signature = c("qenv", "expression"), function(object, cod
6163
invokeRestart("muffleMessage")
6264
}
6365
)
66+
6467
if (!is.null(x)) {
6568
return(x)
6669
}
67-
68-
object@warnings <- c(object@warnings, current_warnings)
69-
object@messages <- c(object@messages, current_messages)
7070
}
71+
72+
73+
object@warnings <- c(object@warnings, current_warnings)
74+
object@messages <- c(object@messages, current_messages)
75+
7176
lockEnvironment(object@env, bindings = TRUE)
7277
object
7378
})
7479

7580
#' @rdname eval_code
7681
#' @export
7782
setMethod("eval_code", signature = c("qenv", "language"), function(object, code) {
78-
code_char <- as.expression(code)
79-
eval_code(object, code_char)
83+
eval_code(object, code = format_expression(code))
8084
})
8185

8286
#' @rdname eval_code
8387
#' @export
84-
setMethod("eval_code", signature = c("qenv", "character"), function(object, code) {
85-
eval_code(object, code = parse(text = code, keep.source = FALSE))
88+
setMethod("eval_code", signature = c("qenv", "expression"), function(object, code) {
89+
eval_code(object, code = format_expression(code))
8690
})
8791

8892
#' @rdname eval_code

R/qenv-get_code.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ setGeneric("get_code", function(object, deparse = TRUE) {
2626
setMethod("get_code", signature = "qenv", function(object, deparse = TRUE) {
2727
checkmate::assert_flag(deparse)
2828
if (deparse) {
29-
format_expression(object@code)
30-
} else {
3129
object@code
30+
} else {
31+
parse(text = object@code, keep.source = TRUE)
3232
}
3333
})
3434

0 commit comments

Comments
 (0)