blob: 333a0c2d25114e1460de94ec1d8f78e519b1e78a [file] [log] [blame]
.debugMethod <- function(fun, text = "", condition = NULL, signature,
once = FALSE)
{
stopifnot(is.null(condition), identical(text, ""))
if (is.primitive(fun))
fun <- getGeneric(fun)
if(!is(fun, "genericFunction"))
stop("Function must be an S4 generic")
if(isdebugged(fun, signature = signature))
return(invisible(NULL))
m <- selectMethod(fun, signature)
bd <- body(m)
isrematch <- isRematched(m)
if(isrematch)
bd <- body(bd[[2L]][[3L]])
at <- if(is(bd, "{")) 2L else numeric()
tracer <- if(once) {
## If the method is rematched we're in .local so we need to reach up one
## frame to get the generic and target in that case
if (isrematch)
quote(quote({untrace(sys.frame(2L)$.Generic,
signature = sys.frame(2L)$.target);
browser()}))
else
quote(quote({untrace(.Generic,
signature = .target); browser()}))
} else {
quote(browser)
}
eval(substitute(trace(fun, tracer, signature = signature, print = TRUE,
at = at),
list(tracer=tracer)))
invisible(NULL)
}
.undebugMethod <- function(fun, signature) {
if (!isdebugged(fun, signature)) {
warning("method is not being debugged")
} else {
if (is.primitive(fun))
fun <- getGeneric(fun)
untrace(fun, signature = signature)
}
}
.isMethodDebugged <- function(fun, signature) {
meth <- selectMethod(fun, signature)
if(!is(meth, "MethodDefinitionWithTrace"))
return(FALSE)
bd <- body(meth)
if(isRematched(meth)) {
## detect the .doTrace block that gets inserted.
## This should be specific enough to only catch traces
## added by debug (or fully equivalent trace calls)
is(bd[[3L]], "{") &&
identical(bd[[3L]][[2L]][1L], quote(.doTrace())) &&
identical(bd[[3L]][[2L]][[2L]][1:3],
quote(trace(.local, tracer = browser)))
} else {
fstexp <- bd
## we need to cover function(x) x@y and function(x) {x;y;z} cases
## so peel off brackets until there aren't any, because "debugging"
## here translates to putting .doTrace(browser()) as the first
## non-bracket evaluated expression
while(is(bd, "{"))
bd <- bd[[2L]]
identical(bd[1:2], quote(.doTrace(browser())))
}
}