Skip to content

Commit 29db38f

Browse files
committed
Revamp operation of rd and namespace roclets.
At the heart of both roclets is now a loop that processes each tag in turn, calling `roxy_tag_rd()` or `roxy_tag_ns()`. This makes it easier to closely connected the parsing and processing tag, making the pieces easier to understand. Other changes: * `@docType package` no longer adds `-package` alias as this broke encapsulation and was only mildly useful. * .rexports, .formals, and .methods all now work by defining internal tags in object_defaults. Fixes #915
1 parent f7b0603 commit 29db38f

File tree

14 files changed

+510
-394
lines changed

14 files changed

+510
-394
lines changed

NAMESPACE

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ S3method(merge,roxy_field_minidesc)
5151
S3method(merge,roxy_field_param)
5252
S3method(merge,roxy_field_reexport)
5353
S3method(merge,roxy_field_section)
54+
S3method(object_defaults,"function")
5455
S3method(object_defaults,data)
5556
S3method(object_defaults,default)
5657
S3method(object_defaults,import)
@@ -74,6 +75,19 @@ S3method(roclet_preprocess,roclet_namespace)
7475
S3method(roclet_process,roclet_namespace)
7576
S3method(roclet_process,roclet_rd)
7677
S3method(roclet_process,roclet_vignette)
78+
S3method(roxy_tag_ns,default)
79+
S3method(roxy_tag_ns,roxy_tag_evalNamespace)
80+
S3method(roxy_tag_ns,roxy_tag_export)
81+
S3method(roxy_tag_ns,roxy_tag_exportClass)
82+
S3method(roxy_tag_ns,roxy_tag_exportMethod)
83+
S3method(roxy_tag_ns,roxy_tag_exportPattern)
84+
S3method(roxy_tag_ns,roxy_tag_exportS3Method)
85+
S3method(roxy_tag_ns,roxy_tag_import)
86+
S3method(roxy_tag_ns,roxy_tag_importClassesFrom)
87+
S3method(roxy_tag_ns,roxy_tag_importFrom)
88+
S3method(roxy_tag_ns,roxy_tag_importMethodsFrom)
89+
S3method(roxy_tag_ns,roxy_tag_rawNamespace)
90+
S3method(roxy_tag_ns,roxy_tag_useDynLib)
7791
S3method(roxy_tag_parse,default)
7892
S3method(roxy_tag_parse,roxy_tag_aliases)
7993
S3method(roxy_tag_parse,roxy_tag_author)
@@ -130,6 +144,38 @@ S3method(roxy_tag_parse,roxy_tag_templateVar)
130144
S3method(roxy_tag_parse,roxy_tag_title)
131145
S3method(roxy_tag_parse,roxy_tag_usage)
132146
S3method(roxy_tag_parse,roxy_tag_useDynLib)
147+
S3method(roxy_tag_rd,roxy_tag_.formals)
148+
S3method(roxy_tag_rd,roxy_tag_.methods)
149+
S3method(roxy_tag_rd,roxy_tag_.reexport)
150+
S3method(roxy_tag_rd,roxy_tag_author)
151+
S3method(roxy_tag_rd,roxy_tag_backref)
152+
S3method(roxy_tag_rd,roxy_tag_concept)
153+
S3method(roxy_tag_rd,roxy_tag_description)
154+
S3method(roxy_tag_rd,roxy_tag_details)
155+
S3method(roxy_tag_rd,roxy_tag_docType)
156+
S3method(roxy_tag_rd,roxy_tag_encoding)
157+
S3method(roxy_tag_rd,roxy_tag_evalRd)
158+
S3method(roxy_tag_rd,roxy_tag_example)
159+
S3method(roxy_tag_rd,roxy_tag_examples)
160+
S3method(roxy_tag_rd,roxy_tag_family)
161+
S3method(roxy_tag_rd,roxy_tag_field)
162+
S3method(roxy_tag_rd,roxy_tag_format)
163+
S3method(roxy_tag_rd,roxy_tag_includeRmd)
164+
S3method(roxy_tag_rd,roxy_tag_inherit)
165+
S3method(roxy_tag_rd,roxy_tag_inheritDotParams)
166+
S3method(roxy_tag_rd,roxy_tag_inheritParams)
167+
S3method(roxy_tag_rd,roxy_tag_inheritSection)
168+
S3method(roxy_tag_rd,roxy_tag_keywords)
169+
S3method(roxy_tag_rd,roxy_tag_note)
170+
S3method(roxy_tag_rd,roxy_tag_param)
171+
S3method(roxy_tag_rd,roxy_tag_rawRd)
172+
S3method(roxy_tag_rd,roxy_tag_references)
173+
S3method(roxy_tag_rd,roxy_tag_return)
174+
S3method(roxy_tag_rd,roxy_tag_section)
175+
S3method(roxy_tag_rd,roxy_tag_seealso)
176+
S3method(roxy_tag_rd,roxy_tag_slot)
177+
S3method(roxy_tag_rd,roxy_tag_source)
178+
S3method(roxy_tag_rd,roxy_tag_title)
133179
export(block_get_tag)
134180
export(block_get_tag_value)
135181
export(block_get_tags)

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# roxygen2 (development version)
22

3+
* Using `@docType package` no longer automatically adds `-name`. Instead
4+
document `_PACKAGE` to get all the defaults for package documentation.
5+
(Removing this feature allowed for simplification of the code.)
6+
37
* `roclet_tags()` is no longer used; instead define a `roxy_tag_parse()` method.
48
If you tag is `@mytag`, then the class name associated with it is
59
`roxy_tag_mytag` so the method should be call `roxy_tag_parse.roxy_tag_mytag()`.

R/namespace.R

Lines changed: 153 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
# Processed first
2-
ns_tags_import <- c(
3-
"import",
4-
"importFrom",
5-
"importClassesFrom",
6-
"importMethodsFrom",
7-
"useDynLib",
8-
"rawNamespace"
9-
)
10-
ns_tags <- c(
11-
ns_tags_import,
12-
"evalNamespace",
13-
"export",
14-
"exportClass",
15-
"exportMethod",
16-
"exportS3Method",
17-
"exportPattern"
18-
)
19-
201
#' Roclet: make `NAMESPACE`
212
#'
223
#' @description
@@ -55,15 +36,15 @@ roclet_preprocess.roclet_namespace <- function(x,
5536
base_path,
5637
global_options = list()) {
5738

58-
lines <- blocks_to_ns(blocks, env, tag_set = ns_tags_import)
39+
lines <- blocks_to_ns(blocks, env, import_only = TRUE)
5940
NAMESPACE <- file.path(base_path, "NAMESPACE")
6041

6142
if (length(lines) == 0 && !made_by_roxygen(NAMESPACE)) {
6243
return(x)
6344
}
6445

6546
results <- c(made_by("#"), lines)
66-
write_if_different(NAMESPACE, results, check = FALSE)
47+
write_if_different(NAMESPACE, results, check = TRUE)
6748

6849
invisible(x)
6950
}
@@ -77,30 +58,6 @@ roclet_process.roclet_namespace <- function(x,
7758
blocks_to_ns(blocks, env)
7859
}
7960

80-
#' @export
81-
roxy_tag_parse.roxy_tag_evalNamespace <- function(x) tag_code(x)
82-
#' @export
83-
roxy_tag_parse.roxy_tag_export <- function(x) tag_words_line(x)
84-
#' @export
85-
roxy_tag_parse.roxy_tag_exportClass <- function(x) tag_words(x, 1)
86-
#' @export
87-
roxy_tag_parse.roxy_tag_exportS3Method <- function(x) tag_words(x, min = 0, max = 2)
88-
#' @export
89-
roxy_tag_parse.roxy_tag_exportMethod <- function(x) tag_words(x, min = 1)
90-
#' @export
91-
roxy_tag_parse.roxy_tag_exportPattern <- function(x) tag_words(x, min = 1)
92-
#' @export
93-
roxy_tag_parse.roxy_tag_import <- function(x) tag_words(x, min = 1)
94-
#' @export
95-
roxy_tag_parse.roxy_tag_importClassesFrom <- function(x) tag_words(x, min = 2)
96-
#' @export
97-
roxy_tag_parse.roxy_tag_importFrom <- function(x) tag_words(x, min = 2)
98-
#' @export
99-
roxy_tag_parse.roxy_tag_importMethodsFrom <- function(x) tag_words(x, min = 2)
100-
#' @export
101-
roxy_tag_parse.roxy_tag_rawNamespace <- function(x) tag_code(x)
102-
#' @export
103-
roxy_tag_parse.roxy_tag_useDynLib <- function(x) tag_words(x, min = 1)
10461

10562
#' @export
10663
roclet_output.roclet_namespace <- function(x, results, base_path, ...) {
@@ -124,86 +81,185 @@ roclet_clean.roclet_namespace <- function(x, base_path) {
12481

12582
# NAMESPACE generation ----------------------------------------------------
12683

127-
blocks_to_ns <- function(blocks, env, tag_set = ns_tags) {
128-
lines <- map(blocks, block_to_ns, env = env, tag_set = tag_set)
84+
blocks_to_ns <- function(blocks, env, import_only = FALSE) {
85+
lines <- map(blocks, block_to_ns, env = env, import_only = import_only)
12986
lines <- unlist(lines) %||% character()
13087

13188
sort_c(unique(lines))
13289
}
13390

134-
block_to_ns <- function(block, env, tag_set = ns_tags) {
135-
tags <- block_get_tags(block, tag_set)
91+
block_to_ns <- function(block, env, import_only = FALSE) {
92+
map(block$tags, roxy_tag_ns, block = block, env = env, import_only = import_only)
93+
}
94+
95+
# Namespace tag methods ---------------------------------------------------
13696

137-
map(tags, function(tag) {
138-
exec(paste0("ns_", tag$tag), tag, block, env)
139-
})
97+
roxy_tag_ns <- function(x, block, env, import_only = FALSE) {
98+
UseMethod("roxy_tag_ns")
14099
}
141100

142-
ns_export <- function(tag, block, env) {
143-
if (identical(tag$val, "")) {
101+
#' @export
102+
roxy_tag_ns.default <- function(x, block, env, import_only = FALSE) {
103+
104+
}
105+
106+
#' @export
107+
roxy_tag_parse.roxy_tag_evalNamespace <- function(x) {
108+
tag_code(x)
109+
}
110+
#' @export
111+
roxy_tag_ns.roxy_tag_evalNamespace <- function(x, block, env, import_only = FALSE) {
112+
roxy_tag_eval(x, env)
113+
}
114+
115+
#' @export
116+
roxy_tag_parse.roxy_tag_export <- function(x) {
117+
tag_words_line(x)
118+
}
119+
#' @export
120+
roxy_tag_ns.roxy_tag_export <- function(x, block, env, import_only = FALSE) {
121+
if (import_only) {
122+
return()
123+
}
124+
125+
if (identical(x$val, "")) {
144126
# FIXME: check for empty exports (i.e. no name)
145127
default_export(block$object, block)
146128
} else {
147-
export(tag$val)
129+
export(x$val)
148130
}
149131
}
150132

151-
ns_exportClass <- function(tag, block, env) export_class(tag$val)
152-
ns_exportMethod <- function(tag, block, env) export_s4_method(tag$val)
153-
ns_exportPattern <- function(tag, block, env) one_per_line("exportPattern", tag$val)
154-
ns_import <- function(tag, block, env) one_per_line("import", tag$val)
155-
ns_importFrom <- function(tag, block, env) repeat_first("importFrom", tag$val)
156-
ns_importClassesFrom <- function(tag, block, env) repeat_first("importClassesFrom", tag$val)
157-
ns_importMethodsFrom <- function(tag, block, env) repeat_first("importMethodsFrom", tag$val)
133+
#' @export
134+
roxy_tag_parse.roxy_tag_exportClass <- function(x) {
135+
tag_words(x, 1)
136+
}
137+
#' @export
138+
roxy_tag_ns.roxy_tag_exportClass <- function(x, block, env, import_only = FALSE) {
139+
if (import_only) {
140+
return()
141+
}
158142

159-
ns_exportS3Method <- function(tag, block, env) {
160-
obj <- block$object
143+
export_class(x$val)
144+
}
145+
146+
#' @export
147+
roxy_tag_parse.roxy_tag_exportMethod <- function(x) {
148+
tag_words(x, min = 1)
149+
}
150+
#' @export
151+
roxy_tag_ns.roxy_tag_exportMethod <- function(x, block, env, import_only = FALSE) {
152+
if (import_only) {
153+
return()
154+
}
155+
export_s4_method(x$val)
156+
}
161157

162-
if (length(tag$val) < 2 && !inherits(obj, "s3method")) {
163-
roxy_tag_warning(tag,
158+
#' @export
159+
roxy_tag_parse.roxy_tag_exportPattern <- function(x) {
160+
tag_words(x, min = 1)
161+
}
162+
#' @export
163+
roxy_tag_ns.roxy_tag_exportPattern <- function(x, block, env, import_only = FALSE) {
164+
if (import_only) {
165+
return()
166+
}
167+
one_per_line("exportPattern", x$val)
168+
}
169+
170+
#' @export
171+
roxy_tag_parse.roxy_tag_exportS3Method <- function(x) {
172+
tag_words(x, min = 0, max = 2)
173+
}
174+
#' @export
175+
roxy_tag_ns.roxy_tag_exportS3Method <- function(x, block, env, import_only = FALSE) {
176+
if (import_only) {
177+
return()
178+
}
179+
180+
obj <- block$object
181+
if (length(x$val) < 2 && !inherits(obj, "s3method")) {
182+
roxy_tag_warning(x,
164183
"`@exportS3Method` and `@exportS3Method generic` must be used with an S3 method"
165184
)
166185
return()
167186
}
168187

169-
if (identical(tag$val, "")) {
188+
if (identical(x$val, "")) {
170189
method <- attr(obj$value, "s3method")
171-
} else if (length(tag$val) == 1) {
172-
method <- c(tag$val, attr(obj$value, "s3method")[[2]])
190+
} else if (length(x$val) == 1) {
191+
method <- c(x$val, attr(obj$value, "s3method")[[2]])
173192
} else {
174-
method <- tag$val
193+
method <- x$val
175194
}
176195

177196
export_s3_method(method)
178197
}
179198

180-
ns_useDynLib <- function(tag, block, env) {
181-
if (length(tag$val) == 1) {
182-
return(paste0("useDynLib(", auto_quote(tag$val), ")"))
199+
#' @export
200+
roxy_tag_parse.roxy_tag_import <- function(x) {
201+
tag_words(x, min = 1)
202+
}
203+
#' @export
204+
roxy_tag_ns.roxy_tag_import <- function(x, block, env, import_only = FALSE) {
205+
one_per_line("import", x$val)
206+
}
207+
208+
#' @export
209+
roxy_tag_parse.roxy_tag_importClassesFrom <- function(x) {
210+
tag_words(x, min = 2)
211+
}
212+
#' @export
213+
roxy_tag_ns.roxy_tag_importClassesFrom <- function(x, block, env, import_only = FALSE) {
214+
repeat_first("importClassesFrom", x$val)
215+
}
216+
217+
#' @export
218+
roxy_tag_parse.roxy_tag_importFrom <- function(x) {
219+
tag_words(x, min = 2)
220+
}
221+
#' @export
222+
roxy_tag_ns.roxy_tag_importFrom <- function(x, block, env, import_only = FALSE) {
223+
repeat_first("importFrom", x$val)
224+
}
225+
226+
#' @export
227+
roxy_tag_parse.roxy_tag_importMethodsFrom <- function(x) {
228+
tag_words(x, min = 2)
229+
}
230+
#' @export
231+
roxy_tag_ns.roxy_tag_importMethodsFrom <- function(x, block, env, import_only = FALSE) {
232+
repeat_first("importMethodsFrom", x$val)
233+
}
234+
235+
#' @export
236+
roxy_tag_parse.roxy_tag_rawNamespace <- function(x) {
237+
tag_code(x)
238+
}
239+
#' @export
240+
roxy_tag_ns.roxy_tag_rawNamespace <- function(x, block, env, import_only = FALSE) {
241+
x$val
242+
}
243+
244+
#' @export
245+
roxy_tag_parse.roxy_tag_useDynLib <- function(x) {
246+
tag_words(x, min = 1)
247+
}
248+
#' @export
249+
roxy_tag_ns.roxy_tag_useDynLib <- function(x, block, env, import_only = FALSE) {
250+
if (length(x$val) == 1) {
251+
return(paste0("useDynLib(", auto_quote(x$val), ")"))
183252
}
184253

185-
if (any(grepl(",", tag$val))) {
254+
if (any(grepl(",", x$val))) {
186255
# If there's a comma in list, don't quote output. This makes it possible
187256
# for roxygen2 to support other NAMESPACE forms not otherwise mapped
188-
args <- paste0(tag$val, collapse = " ")
257+
args <- paste0(x$val, collapse = " ")
189258
paste0("useDynLib(", args, ")")
190259
} else {
191-
repeat_first("useDynLib", tag$val)
260+
repeat_first("useDynLib", x$val)
192261
}
193262
}
194-
ns_rawNamespace <- function(tag, block, env) tag$val
195-
ns_evalNamespace <- function(tag, block, env) {
196-
roxy_tag_eval(tag, env)
197-
}
198-
199-
# Functions used by both default_export and ns_* functions
200-
export <- function(x) one_per_line("export", x)
201-
export_class <- function(x) one_per_line("exportClasses", x)
202-
export_s4_method <- function(x) one_per_line("exportMethods", x)
203-
export_s3_method <- function(x) {
204-
args <- paste0(auto_backtick(x), collapse = ",")
205-
paste0("S3method(", args, ")")
206-
}
207263

208264
# Default export methods --------------------------------------------------
209265

@@ -223,9 +279,16 @@ default_export.default <- function(x, block) export(x$alias)
223279
#' @export
224280
default_export.NULL <- function(x, block) export(block_get_tag_value(block, "name"))
225281

226-
227282
# Helpers -----------------------------------------------------------------
228283

284+
export <- function(x) one_per_line("export", x)
285+
export_class <- function(x) one_per_line("exportClasses", x)
286+
export_s4_method <- function(x) one_per_line("exportMethods", x)
287+
export_s3_method <- function(x) {
288+
args <- paste0(auto_backtick(x), collapse = ",")
289+
paste0("S3method(", args, ")")
290+
}
291+
229292
one_per_line <- function(name, x) {
230293
paste0(name, "(", auto_backtick(x), ")")
231294
}

0 commit comments

Comments
 (0)