The R Project SVN R

Rev

Rev 85253 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 85253 Rev 85261
Line 1... Line 1...
1
## check that the 'internal generics' are indeed generic.
1
## check that the 'internal generics' are indeed generic.
2
 
2
 
3
x <- structure(pi, class="testit")
3
x <- structure(pi, class="testit")
4
xx <- structure("OK", class="testOK")
4
xx <- structure("OK", class="testOK")
5
 
5
 
6
for(f in ls(.GenericArgsEnv, all.names=TRUE))
6
internalGenerics <- ls(.GenericArgsEnv, all.names=TRUE)
-
 
7
for(f in internalGenerics)
7
{
8
{
8
    cat("testing S3 generic '", f, "'\n", sep="")
9
    cat("testing S3 generic '", f, "'\n", sep="")
9
    method <- paste(f, "testit", sep=".")
10
    method <- paste(f, "testit", sep=".")
10
    if(f %in% "seq.int") {
11
    if(f == "seq.int") {
11
        ## note that this dispatches on 'seq'.
12
        ## note that this dispatches on 'seq'.
12
        assign("seq.testit", function(...) xx, .GlobalEnv)
13
        assign("seq.testit", function(...) xx, .GlobalEnv)
13
        res <- seq.int(x, x)
14
        res <- seq.int(x, x)
14
    } else {
15
    } else {
15
        if(length(grep("<-$", f)) > 0) {
16
        if(grepl("<-$", f)) {
16
            assign(method, function(x, value) xx, .GlobalEnv)
17
            assign(method, function(x, value) xx, .GlobalEnv)
17
            y <- x
18
            y <- x
18
            res <- eval(substitute(ff(y, value=pi), list(ff=as.name(f))))
19
            res <- eval(substitute(ff(y, value=pi), list(ff=as.name(f))))
19
        } else {
20
        } else {
20
            ff <- get(f, .GenericArgsEnv)
21
            ff <- get(f, .GenericArgsEnv)
21
            body(ff) <- xx
22
            body(ff) <- xx
22
            assign(method, ff, .GlobalEnv)
23
            assign(method, ff, .GlobalEnv)
-
 
24
            res <- if(f %in% "%*%") # 2 args
-
 
25
                        eval(substitute(ff(x,x), list(ff=as.name(f))))
23
            res <- eval(substitute(ff(x), list(ff=as.name(f))))
26
                   else eval(substitute(ff(x),   list(ff=as.name(f))))
24
        }
27
        }
25
    }
28
    }
26
    stopifnot(res == xx)
29
    stopifnot(res == xx)
27
    rm(method)
30
    rm(method)
28
}
31
}
Line 51... Line 54...
51
## apart from the language elements:
54
## apart from the language elements:
52
ff <- as.list(baseenv(), all.names=TRUE)
55
ff <- as.list(baseenv(), all.names=TRUE)
53
ff <- names(ff)[vapply(ff, is.primitive, logical(1L))]
56
ff <- names(ff)[vapply(ff, is.primitive, logical(1L))]
54
 
57
 
55
known <- c(names(.GenericArgsEnv), names(.ArgsEnv), tools::langElts)
58
known <- c(names(.GenericArgsEnv), names(.ArgsEnv), tools::langElts)
56
stopifnot(ff %in% known, known %in% ff)
59
stopifnot(ff %in% known, known %in% ff) ## identical(ff, known) "modulo sort()"
57
 
60
 
58
 
61
 
59
## check which are not considered as possibles for S4 generic
62
## check which are not considered as possibles for S4 generic (*all* should)
60
ff4 <- names(meth.FList <- methods:::.BasicFunsList)
63
ff4 <- names(meth.FList <- methods:::.BasicFunsList)
61
# as.double is the same as as.numeric
64
# as.double is the same as as.numeric
62
S4generic <- ff %in% c(ff4, "as.double")
65
S4generic <- ff %in% c(ff4, "as.double")
63
notS4 <- ff[!S4generic]
66
notS4 <- ff[!S4generic]
64
if(length(notS4))
67
if(length(notS4))
65
    cat("primitives not covered in methods:::.BasicFunsList:",
68
    cat("primitives not covered in methods:::.BasicFunsList:",
66
        paste(sQuote(notS4), collapse=", "), "\n")
69
        paste(sQuote(notS4), collapse=", "), "\n")
67
stopifnot(S4generic)
70
stopifnot(S4generic)
68
 
71
 
69
# functions which are listed but not primitive
72
# functions which are listed but not primitive
70
extraS4 <- c('unlist', 'as.vector', 'lengths')
73
extraS4 <- c('unlist', 'as.vector', 'lengths') # == setdiff(ff4, ff)
71
ff4[!ff4 %in% c(ff, extraS4)]
74
ff4[!ff4 %in% c(ff, extraS4)]
72
stopifnot(ff4 %in% c(ff, extraS4))
75
stopifnot(ff4 %in% c(ff, extraS4))
73
 
76
 
74
 
77
 
75
## primitives which are not internally generic cannot have S4 methods
78
## primitives which are not internally generic cannot have S4 methods
76
## unless specifically arranged (e.g. %*%)
79
## unless specifically arranged (e.g. %*%)
77
nongen_prims <- ff[!ff %in% ls(.GenericArgsEnv, all.names=TRUE)]
80
nongen_prims <- ff[!ff %in% internalGenerics]
78
ff3 <- ff4[vapply(meth.FList, function(x) is.logical(x) && !x, NA, USE.NAMES=FALSE)]
81
ff3 <- ff4[vapply(meth.FList, function(x) is.logical(x) && !x, NA, USE.NAMES=FALSE)]
-
 
82
ex <- nongen_prims[!nongen_prims %in%
79
ex <- nongen_prims[!nongen_prims %in% c("$", "$<-", "[", "[[" ,"[[<-", "[<-", "%*%", ff3)]
83
                   c("$", "$<-", "[", "[[" ,"[[<-", "[<-"
-
 
84
                   , "%*%", "crossprod", "tcrossprod"
-
 
85
                   , ff3)]
80
if(length(ex))
86
if(length(ex))
81
    cat("non-generic primitives not excluded in methods:::.BasicFunsList:",
87
    cat("non-generic primitives not excluded in methods:::.BasicFunsList:",
82
        paste(sQuote(ex), collapse=", "), "\n")
88
        paste(sQuote(ex), collapse=", "), "\n")
83
stopifnot(length(ex) == 0)
89
stopifnot(length(ex) == 0)
84
 
90
 
Line 106... Line 112...
106
 
112
 
107
## check that they do argument matching, or at least check names
113
## check that they do argument matching, or at least check names
108
except <- c("call", "switch", ".C", ".Fortran", ".Call", ".External",
114
except <- c("call", "switch", ".C", ".Fortran", ".Call", ".External",
109
            ".External2", ".Call.graphics", ".External.graphics",
115
            ".External2", ".Call.graphics", ".External.graphics",
110
            ".subset", ".subset2", ".primTrace", ".primUntrace",
116
            ".subset", ".subset2", ".primTrace", ".primUntrace",
111
            "lazyLoadDBfetch", ".Internal", ".Primitive", "^", "|",
117
            "lazyLoadDBfetch", ".Internal", ".Primitive",
-
 
118
            unlist(lapply(c("Arith", "Compare", "Logic"), getGroupMembers)),
-
 
119
            "%*%", "crossprod", "tcrossprod", # "matrixOps"
-
 
120
            "!", "::", ":::",
112
            "::", ":::", "%*%", "rep", "seq.int", "forceAndCall",
121
            "rep", "seq.int", "forceAndCall",
113
            "Tailcall",
122
            "Tailcall",
114
            ## these may not be enabled
123
            ## these may not be enabled
115
            "tracemem", "retracemem", "untracemem")
124
            "tracemem", "retracemem", "untracemem")
116
 
125
 
117
for(f in ls(.GenericArgsEnv, all.names=TRUE)[-(1:15)])
126
for(f in internalGenerics)
118
{
127
{
119
    if (f %in% except) next
128
    if (f %in% except) next
120
    g <- get(f, envir = .GenericArgsEnv)
129
    g <- get(f, envir = .GenericArgsEnv)
121
    an <- names(formals(args(g)))
130
    an <- names(formals(args(g)))
122
    if(length(an) > 0 && an[1] == "...") next
131
    if(length(an) > 0 && an[1] == "...") next
Line 124... Line 133...
124
    a <- rep(list(NULL), length(an))
133
    a <- rep(list(NULL), length(an))
125
    names(a) <- c("zZ", an[-1])
134
    names(a) <- c("zZ", an[-1])
126
    res <- try(do.call(f, a), silent = TRUE)
135
    res <- try(do.call(f, a), silent = TRUE)
127
    m <- geterrmessage()
136
    m <- geterrmessage()
128
    if(!grepl('does not match|unused argument', m))
137
    if(!grepl('does not match|unused argument', m))
-
 
138
        ## message("failure on ", f,":\n\t\t", m)
129
        stop("failure on ", f)
139
        stop("failure on ", f,":\n\t", m)
130
}
140
}
131
 
141
 
-
 
142
 
132
for(f in ls(.ArgsEnv, all.names=TRUE))
143
for(f in ls(.ArgsEnv, all.names=TRUE))
133
{
144
{
134
    if (f %in% except) next
145
    if (f %in% except) next
135
    g <- get(f, envir = .ArgsEnv)
146
    g <- get(f, envir = .ArgsEnv)
136
    an <- names(formals(args(g)))
147
    an <- names(formals(args(g)))