|
79 | 79 | #' cut3 <- function(x) cut_number(x, 3) |
80 | 80 | #' scatter_by(mtcars, cut3(disp), drat) |
81 | 81 | aes <- function(x, y, ...) { |
82 | | - exprs <- enquos(x = x, y = y, ..., .ignore_empty = "all") |
83 | | - aes <- new_aes(exprs, env = parent.frame()) |
| 82 | + xs <- arg_enquos("x") |
| 83 | + ys <- arg_enquos("y") |
| 84 | + dots <- enquos(...) |
| 85 | + |
| 86 | + args <- c(xs, ys, dots) |
| 87 | + args <- Filter(Negate(quo_is_missing), args) |
| 88 | + |
| 89 | + # Pass arguments to helper dummy to throw an error when duplicate |
| 90 | + # `x` and `y` arguments are passed through dots |
| 91 | + local({ |
| 92 | + aes <- function(x, y, ...) NULL |
| 93 | + inject(aes(!!!args)) |
| 94 | + }) |
| 95 | + |
| 96 | + aes <- new_aes(args, env = parent.frame()) |
84 | 97 | rename_aes(aes) |
85 | 98 | } |
86 | 99 |
|
@@ -426,3 +439,26 @@ extract_target_is_likely_data <- function(x, data, env) { |
426 | 439 | identical(data_eval, data) |
427 | 440 | }, error = function(err) FALSE) |
428 | 441 | } |
| 442 | + |
| 443 | +# Takes a quosure and returns a named list of quosures, expanding |
| 444 | +# `!!!` expressions as needed |
| 445 | +arg_enquos <- function(name, frame = caller_env()) { |
| 446 | + # First start with `enquo0()` which does not process injection |
| 447 | + # operators |
| 448 | + quo <- inject(enquo0(!!sym(name)), frame) |
| 449 | + expr <- quo_get_expr(quo) |
| 450 | + |
| 451 | + if (!is_missing(expr) && is_triple_bang(expr)) { |
| 452 | + # Evaluate `!!!` operand and create a list of quosures |
| 453 | + env <- quo_get_env(quo) |
| 454 | + xs <- eval_bare(expr[[2]][[2]][[2]], env) |
| 455 | + xs <- lapply(xs, as_quosure, env = env) |
| 456 | + } else { |
| 457 | + # Redefuse `x` to process injection operators, then store in a |
| 458 | + # length-1 list of quosures |
| 459 | + quo <- inject(enquo(!!sym(name)), frame) |
| 460 | + xs <- set_names(list(quo), name) |
| 461 | + } |
| 462 | + |
| 463 | + new_quosures(xs) |
| 464 | +} |
0 commit comments