Skip to content

Commit 84875c7

Browse files
committed
move @id, @warnings and @message to attributes of code and fix rest of the codebase #70
1 parent ed60b32 commit 84875c7

14 files changed

+146
-142
lines changed

R/qenv-concat.R

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@
3232
setGeneric("concat", function(x, y) standardGeneric("concat"))
3333

3434
setMethod("concat", signature = c("qenv", "qenv"), function(x, y) {
35-
y@id <- c(x@id, y@id)
3635
y@code <- c(x@code, y@code)
37-
y@warnings <- c(x@warnings, y@warnings)
38-
y@messages <- c(x@messages, y@messages)
3936

4037
# insert (and overwrite) objects from y to x
4138
y@env <- rlang::env_clone(y@env, parent = parent.env(.GlobalEnv))

R/qenv-eval_code.R

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ setMethod("eval_code", signature = c("qenv", "character"), function(object, code
3939
for (i in seq_along(code_split)) {
4040
current_code <- code_split[[i]]
4141
current_call <- parse(text = current_code, keep.source = FALSE)
42-
new_object_code <- c(object@code, list(current_code))
4342

4443
# Using withCallingHandlers to capture warnings and messages.
4544
# Using tryCatch to capture the error and abort further evaluation.
@@ -62,7 +61,7 @@ setMethod("eval_code", signature = c("qenv", "character"), function(object, code
6261
deparse1(current_call)
6362
),
6463
class = c("qenv.error", "try-error", "simpleError"),
65-
trace = unlist(new_object_code)
64+
trace = unlist(c(object@code, list(current_code)))
6665
)
6766
}
6867
),
@@ -81,7 +80,7 @@ setMethod("eval_code", signature = c("qenv", "character"), function(object, code
8180
}
8281

8382
attr(current_code, "id") <- sample.int(.Machine$integer.max, size = 1)
84-
object@code <- new_object_code
83+
object@code <- c(object@code, list(current_code))
8584
}
8685

8786
lockEnvironment(object@env, bindings = TRUE)
@@ -109,3 +108,8 @@ setMethod("eval_code", signature = c("qenv.error", "ANY"), function(object, code
109108
chr
110109
}
111110
}
111+
112+
get_code_attr <- function(qenv, attr){
113+
#unlist(lapply(qenv@code, attr, attr)) # somehow doesn't work
114+
unlist(lapply(qenv@code, function(x) attr(x, attr)))
115+
}

R/qenv-get_code.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ setMethod("get_code", signature = "qenv", function(object, deparse = TRUE, names
125125
}
126126

127127
if (deparse) {
128-
unlist(code)
128+
code
129129
} else {
130130
parse(text = paste(c("{", unlist(code), "}"), collapse = "\n"), keep.source = TRUE)
131131
}

R/qenv-get_warnings.R

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ setGeneric("get_warnings", function(object) {
3333
})
3434

3535
setMethod("get_warnings", signature = c("qenv"), function(object) {
36-
if (all(object@warnings == "")) {
36+
warnings <- lapply(object@code, "attr", "warning")
37+
code <- object@code[unlist(lapply(warnings, Negate(is.null)))]
38+
if (length(unlist(warnings)) == 0) {
3739
return(NULL)
3840
}
3941

@@ -44,8 +46,8 @@ setMethod("get_warnings", signature = c("qenv"), function(object) {
4446
}
4547
sprintf("%swhen running code:\n%s", warn, paste(lang2calls(expr), collapse = "\n"))
4648
},
47-
warn = as.list(object@warnings),
48-
expr = as.list(as.character(object@code))
49+
warn = as.list(unlist(warnings)),
50+
expr = as.list(unlist(code))
4951
)
5052
lines <- Filter(Negate(is.null), lines)
5153

R/qenv-join.R

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,8 @@ setMethod("join", signature = c("qenv", "qenv"), function(x, y) {
143143
stop(join_validation)
144144
}
145145

146-
id_unique <- !y@id %in% x@id
147-
x@id <- c(x@id, y@id[id_unique])
146+
id_unique <- !get_code_attr(y, "id") %in% get_code_attr(x, "id")
148147
x@code <- c(x@code, y@code[id_unique])
149-
x@warnings <- c(x@warnings, y@warnings[id_unique])
150-
x@messages <- c(x@messages, y@messages[id_unique])
151148

152149
# insert (and overwrite) objects from y to x
153150
x@env <- rlang::env_clone(x@env, parent = parent.env(.GlobalEnv))
@@ -188,14 +185,16 @@ setMethod("join", signature = c("qenv.error", "ANY"), function(x, y) {
188185
)
189186
)
190187
}
188+
x_id <- get_code_attr(x, "id")
189+
y_id <- get_code_attr(y, "id")
191190

192-
shared_ids <- intersect(x@id, y@id)
191+
shared_ids <- intersect(x_id, y_id)
193192
if (length(shared_ids) == 0) {
194193
return(TRUE)
195194
}
196195

197-
shared_in_x <- match(shared_ids, x@id)
198-
shared_in_y <- match(shared_ids, y@id)
196+
shared_in_x <- match(shared_ids, x_id)
197+
shared_in_y <- match(shared_ids, y_id)
199198

200199
# indices of shared ids should be 1:n in both slots
201200
if (identical(shared_in_x, shared_in_y) && identical(shared_in_x, seq_along(shared_ids))) {

R/utils-get_code_dependency.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ get_code_dependency <- function(code, names, check_names = TRUE) {
3737
# TODO: rethink if this is still needed when code is divided by calls?
3838
tcode <- trimws(code)
3939
if (any(grepl("^\\{.*\\}$", tcode))) {
40-
code <- sub("^\\{(.*)\\}$", "\\1", tcode)
40+
tcode <- sub("^\\{(.*)\\}$", "\\1", tcode)
4141
}
4242

43-
parsed_code <- parse(text = code, keep.source = TRUE)
43+
parsed_code <- parse(text = tcode, keep.source = TRUE)
4444

4545
pd <- utils::getParseData(parsed_code)
4646
pd <- normalize_pd(pd)

tests/testthat/test-qenv_concat.R

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ testthat::test_that("Concatenate two identical qenvs outputs", {
77

88
testthat::expect_equal(q12@env, q1@env)
99
testthat::expect_identical(
10-
q12@code,
10+
unlist(q12@code),
1111
c("iris1 <- iris", "iris1 <- iris")
1212
)
1313
})
@@ -23,10 +23,12 @@ testthat::test_that("Concatenate two independent qenvs results in object having
2323

2424
testthat::expect_equal(q12@env, list2env(list(iris1 = iris, mtcars1 = mtcars)))
2525
testthat::expect_identical(
26-
q12@code,
26+
unlist(q12@code),
2727
c("iris1 <- iris", "mtcars1 <- mtcars")
2828
)
29-
testthat::expect_identical(q12@id, c(q1@id, q2@id))
29+
q12_ids <- unlist(lapply(q12@code, "attr", "id"))
30+
q1_q2_ids <- c(attr(q1@code[[1]], "id"), attr(q2@code[[1]], "id"))
31+
testthat::expect_identical(q12_ids, q1_q2_ids)
3032
})
3133

3234
testthat::test_that("Concatenate qenvs results with the same variable, the RHS has priority", {
@@ -57,7 +59,7 @@ testthat::test_that("Concatenate two independent qenvs with warnings results in
5759
q12 <- concat(q1, q2)
5860

5961
testthat::expect_equal(
60-
q12@warnings,
62+
unlist(lapply(q12@code, attr, "warning")),
6163
c(
6264
"> This is warning 1\n",
6365
"> This is warning 2\n"
@@ -72,7 +74,7 @@ testthat::test_that("Concatenate two independent qenvs with messages results in
7274
q12 <- concat(q1, q2)
7375

7476
testthat::expect_equal(
75-
q12@messages,
77+
unlist(lapply(q12@code, attr, "message")),
7678
c(
7779
"> This is message 1\n",
7880
"> This is message 2\n"

tests/testthat/test-qenv_constructor.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ testthat::test_that("constructor returns qenv", {
22
q <- qenv()
33
testthat::expect_s4_class(q, "qenv")
44
testthat::expect_identical(ls(q@env), character(0))
5-
testthat::expect_identical(q@code, character(0))
6-
testthat::expect_identical(q@id, integer(0))
7-
testthat::expect_identical(q@warnings, character(0))
8-
testthat::expect_identical(q@messages, character(0))
5+
testthat::expect_null(unlist(q@code), NULL)
6+
testthat::expect_null(attr(q@code, "id"))
7+
testthat::expect_null(attr(q@code, "warning"))
8+
testthat::expect_null(attr(q@code, "message"))
99
})
1010

1111
testthat::test_that("parent of qenv environment is the parent of .GlobalEnv", {

tests/testthat/test-qenv_eval_code.R

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,21 +41,21 @@ testthat::test_that("getting object from the package namespace works even if lib
4141
testthat::test_that("eval_code works with character", {
4242
q1 <- eval_code(qenv(), "a <- 1")
4343

44-
testthat::expect_identical(q1@code, "a <- 1")
44+
testthat::expect_identical(unlist(q1@code), "a <- 1")
4545
testthat::expect_equal(q1@env, list2env(list(a = 1)))
4646
})
4747

4848
testthat::test_that("eval_code works with expression", {
4949
q1 <- eval_code(qenv(), as.expression(quote(a <- 1)))
5050

51-
testthat::expect_identical(q1@code, "a <- 1")
51+
testthat::expect_identical(unlist(q1@code), "a <- 1")
5252
testthat::expect_equal(q1@env, list2env(list(a = 1)))
5353
})
5454

5555
testthat::test_that("eval_code works with quoted", {
5656
q1 <- eval_code(qenv(), quote(a <- 1))
5757

58-
testthat::expect_identical(q1@code, "a <- 1")
58+
testthat::expect_identical(unlist(q1@code), "a <- 1")
5959
testthat::expect_equal(q1@env, list2env(list(a = 1)))
6060
})
6161

@@ -69,7 +69,7 @@ testthat::test_that("eval_code works with quoted code block", {
6969
)
7070

7171
testthat::expect_equal(
72-
q1@code,
72+
unlist(q1@code),
7373
c("a <- 1", "b <- 2")
7474
)
7575
testthat::expect_equal(q1@env, list2env(list(a = 1, b = 2)))
@@ -96,14 +96,17 @@ testthat::test_that("a warning when calling eval_code returns a qenv object whic
9696
q <- eval_code(q, quote("p <- hist(iris_data[, 'Sepal.Length'], ff = '')"))
9797
testthat::expect_s4_class(q, "qenv")
9898
testthat::expect_equal(
99-
q@warnings,
100-
c("", "> \"ff\" is not a graphical parameter\n")
99+
lapply(q@code, attr, "warning"),
100+
list(NULL, "> \"ff\" is not a graphical parameter\n")
101101
)
102102
})
103103

104104
testthat::test_that("eval_code with a vector of code produces one warning element per code element", {
105105
q <- eval_code(qenv(), c("x <- 1", "y <- 1", "warning('warn1')"))
106-
testthat::expect_equal(c("", "", "> warn1\n"), q@warnings)
106+
testthat::expect_equal(
107+
lapply(q@code, attr, "warning"),
108+
list(NULL, NULL, "> warn1\n")
109+
)
107110
})
108111

109112

@@ -112,9 +115,9 @@ testthat::test_that("a message when calling eval_code returns a qenv object whic
112115
q <- eval_code(q, quote("message('This is a message')"))
113116
testthat::expect_s4_class(q, "qenv")
114117
testthat::expect_equal(
115-
q@messages,
116-
c(
117-
"",
118+
lapply(q@code, attr, "message"),
119+
list(
120+
NULL,
118121
"> This is a message\n"
119122
)
120123
)
@@ -123,6 +126,6 @@ testthat::test_that("a message when calling eval_code returns a qenv object whic
123126
testthat::test_that("eval_code returns a qenv object with empty messages and warnings when none are returned", {
124127
q <- eval_code(qenv(), quote("iris_data <- head(iris)"))
125128
testthat::expect_s4_class(q, "qenv")
126-
testthat::expect_equal(q@messages, "")
127-
testthat::expect_equal(q@warnings, "")
129+
testthat::expect_null(attr(q@code, "message"))
130+
testthat::expect_null(attr(q@code, "warning"))
128131
})

tests/testthat/test-qenv_extract.R

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
testthat::test_that("`[.` returns empty qenv for names not in qenv", {
23
data <- within(qenv(), {
34
x <- 1
@@ -36,7 +37,7 @@ testthat::test_that("`[.` extract proper code", {
3637
object_names <- c("x", "a")
3738
qs <- q[object_names]
3839
testthat::expect_identical(
39-
qs@code,
40+
unlist(qs@code),
4041
c("x<-1", "a<-1")
4142
)
4243
})
@@ -47,7 +48,7 @@ testthat::test_that("`[.` preservers comments in the code", {
4748
q <- eval_code(q, code)
4849
qs <- q[c("x", "a")]
4950
testthat::expect_identical(
50-
qs@code,
51+
unlist(qs@code),
5152
c("x<-1 #comment", "a<-1")
5253
)
5354
})
@@ -59,8 +60,9 @@ testthat::test_that("`[.` extract proper elements of @id, @warnings and @message
5960
q <- eval_code(q, code)
6061
qs <- q[c("x", "a")]
6162

62-
testthat::expect_identical(qs@id, q@id[c(1, 3)])
63-
testthat::expect_identical(qs@code, q@code[c(1, 3)])
64-
testthat::expect_identical(qs@warnings, q@warnings[c(1, 3)])
65-
testthat::expect_identical(qs@messages, q@messages[c(1, 3)])
63+
testthat::expect_identical(get_code_attr(qs, "id"), get_code_attr(q, "id")[c(1, 3)])
64+
testthat::expect_identical(unlist(qs@code), unlist(q@code[c(1, 3)]))
65+
testthat::expect_null(get_code_attr(qs, "warning"))
66+
testthat::expect_null(get_code_attr(qs, "message"))
6667
})
68+

0 commit comments

Comments
 (0)