Skip to content

Commit 42a9174

Browse files
committed
Merge branch 'ns-registry'
2 parents 056fa66 + e0c2a81 commit 42a9174

File tree

5 files changed

+80
-6
lines changed

5 files changed

+80
-6
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,4 @@ importFrom(tools,package_dependencies)
9191
importFrom(tools,parse_Rd)
9292
importFrom(utils,install.packages)
9393
importFrom(whisker,whisker.render)
94+
useDynLib(devtools,nsreg)

R/metadata.r

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#' unload(devtest("load-hooks"))
1919
#' @export
2020
dev_meta <- function(name) {
21-
ns <- .Internal(getRegisteredNamespace(as.name(name)))
21+
ns <- get_namespace(as.name(name))
2222
if (is.null(ns)) {
2323
stop("Namespace not found for ", name, ". Is it loaded?")
2424
}
@@ -34,7 +34,7 @@ dev_meta <- function(name) {
3434
# Create the devtools metadata environment for a package.
3535
# This should be run when packages are loaded by devtools.
3636
create_dev_meta <- function(name) {
37-
ns <- .Internal(getRegisteredNamespace(as.name(name)))
37+
ns <- get_namespace(as.name(name))
3838

3939
if (!is.null(ns$.__DEVTOOLS__)) {
4040
stop("devtools metadata for package ", name, " already exists.")

R/namespace-env.r

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ create_ns_env <- function(pkg = ".") {
4343
env
4444
}
4545

46-
# This is taken directly from base::loadNamespace() in R 2.15.1
46+
# This is taken directly from base::loadNamespace() in R 2.15.1.
47+
# Except .Internal(registerNamespace(name, env)) is replaced by
48+
# register_namespace(name, env)
4749
makeNamespace <- function(name, version = NULL, lib = NULL) {
4850
impenv <- new.env(parent = .BaseNamespaceEnv, hash = TRUE)
4951
attr(impenv, "name") <- paste("imports", name, sep = ":")
@@ -62,7 +64,7 @@ makeNamespace <- function(name, version = NULL, lib = NULL) {
6264
setNamespaceInfo(env, "dynlibs", NULL)
6365
setNamespaceInfo(env, "S3methods", matrix(NA_character_, 0L, 3L))
6466
assign(".__S3MethodsTable__.", new.env(hash = TRUE, parent = baseenv()), envir = env)
65-
.Internal(registerNamespace(name, env))
67+
register_namespace(name, env)
6668
env
6769
}
6870

@@ -139,3 +141,60 @@ is_loaded <- function(pkg = ".") {
139141
pkg <- as.package(pkg)
140142
pkg$package %in% loadedNamespaces()
141143
}
144+
145+
146+
# Returns the namespace registry
147+
#' @useDynLib devtools nsreg
148+
ns_registry <- function() {
149+
.Call(nsreg)
150+
}
151+
152+
153+
# Register a namespace
154+
register_namespace <- function(name = NULL, env = NULL) {
155+
# Be careful about what we allow
156+
if (!is.character(name) || name == "" || length(name) != 1)
157+
stop("'name' must be a non-empty character string.")
158+
159+
if (!is.environment(env))
160+
stop("'env' must be an environment.")
161+
162+
if (name %in% loadedNamespaces())
163+
stop("Namespace ", name, " is already registered.")
164+
165+
# Add the environment to the registry
166+
nsr <- ns_registry()
167+
nsr[[name]] <- env
168+
169+
env
170+
}
171+
172+
173+
# unregister a namespace - should be used only if unloadNamespace()
174+
# fails for some reason
175+
unregister_namespace <- function(name = NULL) {
176+
# Be careful about what we allow
177+
if (!is.character(name) || name == "" || length(name) != 1)
178+
stop("'name' must be a non-empty character string.")
179+
180+
if (!(name %in% loadedNamespaces()))
181+
stop(name, " is not a registered namespace.")
182+
183+
# Remove the item from the registry
184+
rm(name, ns_registry())
185+
invisible()
186+
}
187+
188+
# This is similar to getNamespace(), except that getNamespace will load
189+
# the namespace if it's not already loaded. This function will not.
190+
# In R 2.16, a function called .getNamespace() will have the same effect
191+
# and this will no longer be necessary.
192+
get_namespace <- function(name) {
193+
# Sometimes we'll be passed something like as.name(name), so make sure
194+
# it's a string
195+
name <- as.character(name)
196+
if (!(name %in% loadedNamespaces()))
197+
return(NULL)
198+
else
199+
return(getNamespace(name))
200+
}

R/reload.r

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ unload <- function(pkg = ".") {
7777
# to go away.
7878
# loadedNamespaces() and unloadNamespace() often don't work here
7979
# because things can be in a weird state.
80-
if (!is.null(.Internal(getRegisteredNamespace(pkg$package)))) {
80+
if (!is.null(get_namespace(pkg$package))) {
8181
message("unloadNamespace(\"", pkg$package,
8282
"\") not successful. Forcing unload.")
83-
.Internal(unregisterNamespace(pkg$package))
83+
unregister_namespace(pkg$package)
8484
}
8585

8686
# Clear so that loading the package again will re-read all files
@@ -95,6 +95,14 @@ unload <- function(pkg = ".") {
9595
unload_dll <- function(pkg = ".") {
9696
pkg <- as.package(pkg)
9797

98+
# Special case for devtools - don't unload DLL because we need to be able
99+
# to access nsreg() in the DLL in order to run makeNamespace. This means
100+
# that changes to compiled code in devtools can't be reloaded with
101+
# load_all -- it requires a reinstallation.
102+
if (pkg$package == "devtools") {
103+
return(invisible())
104+
}
105+
98106
pkglibs <- loaded_dlls(pkg)
99107

100108
for (lib in pkglibs) {

src/devtools.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include <R.h>
2+
#include <Rdefines.h>
3+
4+
SEXP nsreg() {
5+
return R_NamespaceRegistry;
6+
}

0 commit comments

Comments
 (0)