| .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()))) |
| } |
| } |