diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 592a6d2b20..b2c8cedc59 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -118,6 +118,7 @@ jobs: - name: Check env: _R_CHECK_CRAN_INCOMING_: false + _R_CHECK_FORCE_SUGGESTS_: ${{ matrix.config.r != 'devel' }} run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") shell: Rscript {0} diff --git a/NAMESPACE b/NAMESPACE index 911f20360e..a9b48ab3a8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -103,7 +103,6 @@ export(enableBookmarking) export(eventReactive) export(exportTestValues) export(exprToFunction) -export(extractStackTrace) export(fileInput) export(fillCol) export(fillPage) @@ -114,7 +113,6 @@ export(fixedRow) export(flowLayout) export(fluidPage) export(fluidRow) -export(formatStackTrace) export(freezeReactiveVal) export(freezeReactiveValue) export(getCurrentOutputInfo) @@ -207,13 +205,8 @@ export(radioButtons) export(reactive) export(reactiveConsole) export(reactiveFileReader) -export(reactivePlot) export(reactivePoll) -export(reactivePrint) -export(reactiveTable) -export(reactiveText) export(reactiveTimer) -export(reactiveUI) export(reactiveVal) export(reactiveValues) export(reactiveValuesToList) @@ -265,7 +258,6 @@ export(shinyUI) export(showBookmarkUrlModal) export(showModal) export(showNotification) -export(showReactLog) export(showTab) export(sidebarLayout) export(sidebarPanel) diff --git a/NEWS.md b/NEWS.md index f798f0f6f2..31ff805dcb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -26,6 +26,8 @@ shiny 1.6.0.9000 * Switched from internal `Stack` class to `fastmap::faststack()`, and used `fastmap::fastqueue()`. (#3176) +* Some long-deprecated functions and function parameters were removed. (#3137) + ### Bug fixes * Closed #3374: `quoToFunction()` now works correctly with nested quosures; and as a result, quasi-quotation with rendering function (e.g., `renderPrint()`, `renderPlot()`, etc) now works as expected with nested quosures. (#3373) diff --git a/R/bootstrap-layout.R b/R/bootstrap-layout.R index 1c57daf84b..bf208899c0 100644 --- a/R/bootstrap-layout.R +++ b/R/bootstrap-layout.R @@ -11,8 +11,6 @@ #' @param ... Elements to include within the page #' @param title The browser window title (defaults to the host URL of the page). #' Can also be set as a side effect of the [titlePanel()] function. -#' @param responsive This option is deprecated; it is no longer optional with -#' Bootstrap 3. #' @inheritParams bootstrapPage #' #' @return A UI defintion that can be passed to the [shinyUI] function. @@ -85,10 +83,9 @@ #' } #' @rdname fluidPage #' @export -fluidPage <- function(..., title = NULL, responsive = deprecated(), theme = NULL, lang = NULL) { +fluidPage <- function(..., title = NULL, theme = NULL, lang = NULL) { bootstrapPage(div(class = "container-fluid", ...), title = title, - responsive = responsive, theme = theme, lang = lang) } @@ -112,8 +109,6 @@ fluidRow <- function(...) { #' #' @param ... Elements to include within the container #' @param title The browser window title (defaults to the host URL of the page) -#' @param responsive This option is deprecated; it is no longer optional with -#' Bootstrap 3. #' @inheritParams bootstrapPage #' #' @return A UI defintion that can be passed to the [shinyUI] function. @@ -153,10 +148,9 @@ fluidRow <- function(...) { #' #' @rdname fixedPage #' @export -fixedPage <- function(..., title = NULL, responsive = deprecated(), theme = NULL, lang = NULL) { +fixedPage <- function(..., title = NULL, theme = NULL, lang = NULL) { bootstrapPage(div(class = "container", ...), title = title, - responsive = responsive, theme = theme, lang = lang) } diff --git a/R/bootstrap.R b/R/bootstrap.R index 7cb7eb6f7a..6b9e43bd00 100644 --- a/R/bootstrap.R +++ b/R/bootstrap.R @@ -14,8 +14,6 @@ NULL #' #' @param ... The contents of the document body. #' @param title The browser window title (defaults to the host URL of the page) -#' @param responsive This option is deprecated; it is no longer optional with -#' Bootstrap 3. #' @param theme One of the following: #' * `NULL` (the default), which implies a "stock" build of Bootstrap 3. #' * A [bslib::bs_theme()] object. This can be used to replace a stock @@ -33,14 +31,7 @@ NULL #' #' @seealso [fluidPage()], [fixedPage()] #' @export -bootstrapPage <- function(..., title = NULL, responsive = deprecated(), theme = NULL, lang = NULL) { - - if (lifecycle::is_present(responsive)) { - shinyDeprecated( - "0.10.2.2", "bootstrapPage(responsive=)", - details = "The 'responsive' argument is no longer used with the latest version of Bootstrap." - ) - } +bootstrapPage <- function(..., title = NULL, theme = NULL, lang = NULL) { args <- list( jqueryDependency(), @@ -387,11 +378,8 @@ collapseSizes <- function(padding) { #' @param collapsible `TRUE` to automatically collapse the navigation #' elements into a menu when the width of the browser is less than 940 pixels #' (useful for viewing on smaller touchscreen device) -#' @param collapsable Deprecated; use `collapsible` instead. #' @param fluid `TRUE` to use a fluid layout. `FALSE` to use a fixed #' layout. -#' @param responsive This option is deprecated; it is no longer optional with -#' Bootstrap 3. #' @param windowTitle The title that should be displayed by the browser window. #' Useful if `title` is not a string. #' @inheritParams bootstrapPage @@ -435,18 +423,11 @@ navbarPage <- function(title, footer = NULL, inverse = FALSE, collapsible = FALSE, - collapsable = deprecated(), fluid = TRUE, - responsive = deprecated(), theme = NULL, windowTitle = title, lang = NULL) { - if (lifecycle::is_present(collapsable)) { - shinyDeprecated("0.10.2.2", "navbarPage(collapsable =)", "navbarPage(collapsible =)") - collapsible <- collapsable - } - # alias title so we can avoid conflicts w/ title in withTags pageTitle <- title @@ -503,7 +484,6 @@ navbarPage <- function(title, # build the page bootstrapPage( title = windowTitle, - responsive = responsive, theme = theme, lang = lang, tags$nav(class=navbarClass, role="navigation", containerDiv), @@ -711,8 +691,6 @@ tabPanelBody <- function(value, ..., icon = NULL) { #' conjunction with [tabPanelBody()] and [updateTabsetPanel()] to control the #' active tab via other input controls. (See example below)} #' } -#' @param position This argument is deprecated; it has been discontinued in -#' Bootstrap 3. #' @inheritParams navbarPage #' @return A tabset that can be passed to [mainPanel()] #' @@ -764,14 +742,7 @@ tabsetPanel <- function(..., selected = NULL, type = c("tabs", "pills", "hidden"), header = NULL, - footer = NULL, - position = deprecated()) { - if (lifecycle::is_present(position)) { - shinyDeprecated( - "0.10.2.2", "bootstrapPage(position =)", - details = "The 'position' argument is no longer used with the latest version of Bootstrap." - ) - } + footer = NULL) { if (!is.null(id)) selected <- restoreInput(id = id, default = selected) diff --git a/R/conditions.R b/R/conditions.R index f71aa26790..18f8616b71 100644 --- a/R/conditions.R +++ b/R/conditions.R @@ -361,82 +361,6 @@ printStackTrace <- function(cond, invisible() } -#' @details `extractStackTrace` takes a list of calls (e.g. as returned -#' from `conditionStackTrace(cond)`) and returns a data frame with one -#' row for each stack frame and the columns `num` (stack frame number), -#' `call` (a function name or similar), and `loc` (source file path -#' and line number, if available). It was deprecated after shiny 1.0.5 because -#' it doesn't support deep stack traces. -#' @rdname stacktrace -#' @export -extractStackTrace <- function(calls, - full = get_devmode_option("shiny.fullstacktrace", FALSE), - offset = getOption("shiny.stacktraceoffset", TRUE)) { - - shinyDeprecated( - "1.0.5", "extractStackTrace()", - details = "Please contact the Shiny team if you were using this functionality." - ) - - srcrefs <- getSrcRefs(calls) - if (offset) { - # Offset calls vs. srcrefs by 1 to make them more intuitive. - # E.g. for "foo [bar.R:10]", line 10 of bar.R will be part of - # the definition of foo(). - srcrefs <- c(utils::tail(srcrefs, -1), list(NULL)) - } - calls <- setSrcRefs(calls, srcrefs) - - callnames <- getCallNames(calls) - - # Hide and show parts of the callstack based on ..stacktrace(on|off).. - if (full) { - toShow <- rep.int(TRUE, length(calls)) - } else { - # Remove stop(), .handleSimpleError(), and h() calls from the end of - # the calls--they don't add any helpful information. But only remove - # the last *contiguous* block of them, and then, only if they are the - # last thing in the calls list. - hideable <- callnames %in% c("stop", ".handleSimpleError", "h") - # What's the last that *didn't* match stop/.handleSimpleError/h? - lastGoodCall <- max(which(!hideable)) - toRemove <- length(calls) - lastGoodCall - # But don't remove more than 5 levels--that's an indication we might - # have gotten it wrong, I guess - if (toRemove > 0 && toRemove < 5) { - calls <- utils::head(calls, -toRemove) - callnames <- utils::head(callnames, -toRemove) - } - - # This uses a ref-counting scheme. It might make sense to switch this - # to a toggling scheme, so the most recent ..stacktrace(on|off).. - # directive wins, regardless of what came before it. - # Also explicitly remove ..stacktraceon.. because it can appear with - # score > 0 but still should never be shown. - score <- rep.int(0, length(callnames)) - score[callnames == "..stacktraceoff.."] <- -1 - score[callnames == "..stacktraceon.."] <- 1 - toShow <- (1 + cumsum(score)) > 0 & !(callnames %in% c("..stacktraceon..", "..stacktraceoff..", "..stacktracefloor..")) - - # doTryCatch, tryCatchOne, and tryCatchList are not informative--they're - # just internals for tryCatch - toShow <- toShow & !(callnames %in% c("doTryCatch", "tryCatchOne", "tryCatchList")) - } - calls <- calls[toShow] - - calls <- rev(calls) # Show in traceback() order - index <- rev(which(toShow)) - width <- floor(log10(max(index))) + 1 - - data.frame( - num = index, - call = getCallNames(calls), - loc = getLocs(calls), - category = getCallCategories(calls), - stringsAsFactors = FALSE - ) -} - stripStackTraces <- function(stackTraces, values = FALSE) { score <- 1L # >=1: show, <=0: hide lapply(seq_along(stackTraces), function(i) { @@ -531,49 +455,12 @@ offsetSrcrefs <- function(calls, offset = TRUE) { # E.g. for "foo [bar.R:10]", line 10 of bar.R will be part of # the definition of foo(). srcrefs <- c(utils::tail(srcrefs, -1), list(NULL)) - calls <- setSrcRefs(calls, srcrefs) } calls } -#' @details `formatStackTrace` is similar to `extractStackTrace`, but -#' it returns a preformatted character vector instead of a data frame. It was -#' deprecated after shiny 1.0.5 because it doesn't support deep stack traces. -#' @param indent A string to prefix every line of the stack trace. -#' @rdname stacktrace -#' @export -formatStackTrace <- function(calls, indent = " ", - full = get_devmode_option("shiny.fullstacktrace", FALSE), - offset = getOption("shiny.stacktraceoffset", TRUE)) { - - shinyDeprecated( - "1.0.5", "formatStackTrace()", - details = "Please contact the Shiny team if you were using this functionality." - ) - - st <- extractStackTrace(calls, full = full, offset = offset) - if (nrow(st) == 0) { - return(character(0)) - } - - width <- floor(log10(max(st$num))) + 1 - paste0( - indent, - formatC(st$num, width = width), - ": ", - mapply(paste0(st$call, st$loc), st$category, FUN = function(name, category) { - if (category == "pkg") - crayon::silver(name) - else if (category == "user") - crayon::blue$bold(name) - else - crayon::white(name) - }) - ) -} - getSrcRefs <- function(calls) { lapply(calls, function(call) { attr(call, "srcref", exact = TRUE) diff --git a/R/graph.R b/R/graph.R index ca01da6351..3c62a861ab 100644 --- a/R/graph.R +++ b/R/graph.R @@ -94,14 +94,7 @@ reactlogShow <- function(time = TRUE) { check_reactlog() reactlog::reactlog_show(reactlog(), time = time) } -#' @describeIn reactlog This function is deprecated. You should use [reactlogShow()] -#' @export -# legacy purposes -showReactLog <- function(time = TRUE) { - shinyDeprecated("1.2.0", "showReactLog()", "reactlogShow()") - reactlogShow(time = time) -} #' @describeIn reactlog Resets the entire reactlog stack. Useful for debugging and removing all prior reactive history. #' @export reactlogReset <- function() { diff --git a/R/shiny.R b/R/shiny.R index 8704ea23bc..a7cce4ea0a 100644 --- a/R/shiny.R +++ b/R/shiny.R @@ -2127,18 +2127,6 @@ ShinySession <- R6Class( }) } } - ), - active = list( - session = function() { - shinyDeprecated( - "0.11.1", "shinysession$session", - details = paste0( - "Attempted to access deprecated shinysession$session object. ", - "Please just access the shinysession object directly." - ) - ) - self - } ) ) diff --git a/R/shinywrappers.R b/R/shinywrappers.R index 217e7dd67c..d8c276b029 100644 --- a/R/shinywrappers.R +++ b/R/shinywrappers.R @@ -918,67 +918,3 @@ checkDT9 <- function(options) { names(options)[i] <- nms10 options } - -# Deprecated functions ------------------------------------------------------ - -#' Deprecated reactive functions -#' -#' @description \lifecycle{superseded} -#' -#' @name deprecatedReactives -#' @keywords internal -NULL - -#' Plot output (deprecated) -#' -#' `reactivePlot` has been replaced by [renderPlot()]. -#' @param func A function. -#' @param width Width. -#' @param height Height. -#' @param ... Other arguments to pass on. -#' @rdname deprecatedReactives -#' @export -reactivePlot <- function(func, width='auto', height='auto', ...) { - shinyDeprecated("0.4.0", "reactivePlot()", "renderPlot()") - renderPlot({ func() }, width=width, height=height, ...) -} - -#' Table output (deprecated) -#' -#' `reactiveTable` has been replaced by [renderTable()]. -#' @rdname deprecatedReactives -#' @export -reactiveTable <- function(func, ...) { - shinyDeprecated("0.4.0", "reactiveTable()", "renderTable()") - renderTable({ func() }) -} - -#' Print output (deprecated) -#' -#' `reactivePrint` has been replaced by [renderPrint()]. -#' @rdname deprecatedReactives -#' @export -reactivePrint <- function(func) { - shinyDeprecated("0.4.0", "reactivePrint()", "renderPrint()") - renderPrint({ func() }) -} - -#' UI output (deprecated) -#' -#' `reactiveUI` has been replaced by [renderUI()]. -#' @rdname deprecatedReactives -#' @export -reactiveUI <- function(func) { - shinyDeprecated("0.4.0", "reactiveUI()", "renderUI()") - renderUI({ func() }) -} - -#' Text output (deprecated) -#' -#' `reactiveText` has been replaced by [renderText()]. -#' @rdname deprecatedReactives -#' @export -reactiveText <- function(func) { - shinyDeprecated("0.4.0", "reactiveText()", "renderText()") - renderText({ func() }) -} diff --git a/man/bootstrapPage.Rd b/man/bootstrapPage.Rd index f5c97ec272..2bae2fac36 100644 --- a/man/bootstrapPage.Rd +++ b/man/bootstrapPage.Rd @@ -5,13 +5,7 @@ \alias{basicPage} \title{Create a Bootstrap page} \usage{ -bootstrapPage( - ..., - title = NULL, - responsive = deprecated(), - theme = NULL, - lang = NULL -) +bootstrapPage(..., title = NULL, theme = NULL, lang = NULL) basicPage(...) } @@ -20,9 +14,6 @@ basicPage(...) \item{title}{The browser window title (defaults to the host URL of the page)} -\item{responsive}{This option is deprecated; it is no longer optional with -Bootstrap 3.} - \item{theme}{One of the following: \itemize{ \item \code{NULL} (the default), which implies a "stock" build of Bootstrap 3. diff --git a/man/deprecatedReactives.Rd b/man/deprecatedReactives.Rd deleted file mode 100644 index d66121cb36..0000000000 --- a/man/deprecatedReactives.Rd +++ /dev/null @@ -1,44 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/shinywrappers.R -\name{deprecatedReactives} -\alias{deprecatedReactives} -\alias{reactivePlot} -\alias{reactiveTable} -\alias{reactivePrint} -\alias{reactiveUI} -\alias{reactiveText} -\title{Deprecated reactive functions} -\usage{ -reactivePlot(func, width = "auto", height = "auto", ...) - -reactiveTable(func, ...) - -reactivePrint(func) - -reactiveUI(func) - -reactiveText(func) -} -\arguments{ -\item{func}{A function.} - -\item{width}{Width.} - -\item{height}{Height.} - -\item{...}{Other arguments to pass on.} -} -\description{ -\lifecycle{superseded} - -\code{reactivePlot} has been replaced by \code{\link[=renderPlot]{renderPlot()}}. - -\code{reactiveTable} has been replaced by \code{\link[=renderTable]{renderTable()}}. - -\code{reactivePrint} has been replaced by \code{\link[=renderPrint]{renderPrint()}}. - -\code{reactiveUI} has been replaced by \code{\link[=renderUI]{renderUI()}}. - -\code{reactiveText} has been replaced by \code{\link[=renderText]{renderText()}}. -} -\keyword{internal} diff --git a/man/fixedPage.Rd b/man/fixedPage.Rd index 17861c41b6..b27dc65149 100644 --- a/man/fixedPage.Rd +++ b/man/fixedPage.Rd @@ -5,13 +5,7 @@ \alias{fixedRow} \title{Create a page with a fixed layout} \usage{ -fixedPage( - ..., - title = NULL, - responsive = deprecated(), - theme = NULL, - lang = NULL -) +fixedPage(..., title = NULL, theme = NULL, lang = NULL) fixedRow(...) } @@ -20,9 +14,6 @@ fixedRow(...) \item{title}{The browser window title (defaults to the host URL of the page)} -\item{responsive}{This option is deprecated; it is no longer optional with -Bootstrap 3.} - \item{theme}{One of the following: \itemize{ \item \code{NULL} (the default), which implies a "stock" build of Bootstrap 3. diff --git a/man/fluidPage.Rd b/man/fluidPage.Rd index 91dd04f508..51e8610fb0 100644 --- a/man/fluidPage.Rd +++ b/man/fluidPage.Rd @@ -5,13 +5,7 @@ \alias{fluidRow} \title{Create a page with fluid layout} \usage{ -fluidPage( - ..., - title = NULL, - responsive = deprecated(), - theme = NULL, - lang = NULL -) +fluidPage(..., title = NULL, theme = NULL, lang = NULL) fluidRow(...) } @@ -21,9 +15,6 @@ fluidRow(...) \item{title}{The browser window title (defaults to the host URL of the page). Can also be set as a side effect of the \code{\link[=titlePanel]{titlePanel()}} function.} -\item{responsive}{This option is deprecated; it is no longer optional with -Bootstrap 3.} - \item{theme}{One of the following: \itemize{ \item \code{NULL} (the default), which implies a "stock" build of Bootstrap 3. diff --git a/man/navbarPage.Rd b/man/navbarPage.Rd index 99871a1a9a..7bd8dde63f 100644 --- a/man/navbarPage.Rd +++ b/man/navbarPage.Rd @@ -15,9 +15,7 @@ navbarPage( footer = NULL, inverse = FALSE, collapsible = FALSE, - collapsable = deprecated(), fluid = TRUE, - responsive = deprecated(), theme = NULL, windowTitle = title, lang = NULL @@ -63,14 +61,9 @@ navigation bar} elements into a menu when the width of the browser is less than 940 pixels (useful for viewing on smaller touchscreen device)} -\item{collapsable}{Deprecated; use \code{collapsible} instead.} - \item{fluid}{\code{TRUE} to use a fluid layout. \code{FALSE} to use a fixed layout.} -\item{responsive}{This option is deprecated; it is no longer optional with -Bootstrap 3.} - \item{theme}{One of the following: \itemize{ \item \code{NULL} (the default), which implies a "stock" build of Bootstrap 3. diff --git a/man/reactlog.Rd b/man/reactlog.Rd index 3f176e2fc3..68db12107b 100644 --- a/man/reactlog.Rd +++ b/man/reactlog.Rd @@ -3,7 +3,6 @@ \name{reactlog} \alias{reactlog} \alias{reactlogShow} -\alias{showReactLog} \alias{reactlogReset} \title{Reactive Log Visualizer} \usage{ @@ -11,8 +10,6 @@ reactlog() reactlogShow(time = TRUE) -showReactLog(time = TRUE) - reactlogReset() } \arguments{ @@ -59,8 +56,6 @@ of the source code of your reactive expressions and observers. \item \code{reactlogShow}: Display a full reactlog graph for all sessions. -\item \code{showReactLog}: This function is deprecated. You should use \code{\link[=reactlogShow]{reactlogShow()}} - \item \code{reactlogReset}: Resets the entire reactlog stack. Useful for debugging and removing all prior reactive history. }} diff --git a/man/stacktrace.Rd b/man/stacktrace.Rd index 3f6227fe45..98f4d09319 100644 --- a/man/stacktrace.Rd +++ b/man/stacktrace.Rd @@ -6,8 +6,6 @@ \alias{withLogErrors} \alias{printError} \alias{printStackTrace} -\alias{extractStackTrace} -\alias{formatStackTrace} \alias{conditionStackTrace} \alias{conditionStackTrace<-} \alias{..stacktraceon..} @@ -34,19 +32,6 @@ printStackTrace( offset = getOption("shiny.stacktraceoffset", TRUE) ) -extractStackTrace( - calls, - full = get_devmode_option("shiny.fullstacktrace", FALSE), - offset = getOption("shiny.stacktraceoffset", TRUE) -) - -formatStackTrace( - calls, - indent = " ", - full = get_devmode_option("shiny.fullstacktrace", FALSE), - offset = getOption("shiny.stacktraceoffset", TRUE) -) - conditionStackTrace(cond) conditionStackTrace(cond) <- value @@ -72,8 +57,6 @@ left alone (traditional R treatment where the srcref is of the callsite).} \item{cond}{A condition that may have previously been annotated by \code{captureStackTraces} (or \code{withLogErrors}).} -\item{indent}{A string to prefix every line of the stack trace.} - \item{value}{The stack trace value to assign to the condition.} } \value{ @@ -108,17 +91,6 @@ to \code{withLogErrors}. \code{warning(immediate.=TRUE)}. \code{printStackTrace} prints the stack trace only. -\code{extractStackTrace} takes a list of calls (e.g. as returned -from \code{conditionStackTrace(cond)}) and returns a data frame with one -row for each stack frame and the columns \code{num} (stack frame number), -\code{call} (a function name or similar), and \code{loc} (source file path -and line number, if available). It was deprecated after shiny 1.0.5 because -it doesn't support deep stack traces. - -\code{formatStackTrace} is similar to \code{extractStackTrace}, but -it returns a preformatted character vector instead of a data frame. It was -deprecated after shiny 1.0.5 because it doesn't support deep stack traces. - \code{conditionStackTrace} and \verb{conditionStackTrace<-} are accessor functions for getting/setting stack traces on conditions. diff --git a/man/tabsetPanel.Rd b/man/tabsetPanel.Rd index 52751595d9..2373aca535 100644 --- a/man/tabsetPanel.Rd +++ b/man/tabsetPanel.Rd @@ -10,8 +10,7 @@ tabsetPanel( selected = NULL, type = c("tabs", "pills", "hidden"), header = NULL, - footer = NULL, - position = deprecated() + footer = NULL ) } \arguments{ @@ -39,9 +38,6 @@ tabPanels.} \item{footer}{Tag or list of tags to display as a common footer below all tabPanels} - -\item{position}{This argument is deprecated; it has been discontinued in -Bootstrap 3.} } \value{ A tabset that can be passed to \code{\link[=mainPanel]{mainPanel()}} diff --git a/tests/testthat/test-stacks.R b/tests/testthat/test-stacks.R index 6b0edff2bb..178cae270f 100644 --- a/tests/testthat/test-stacks.R +++ b/tests/testthat/test-stacks.R @@ -32,6 +32,77 @@ causeError <- function(full) { df } +#' @details `extractStackTrace` takes a list of calls (e.g. as returned +#' from `conditionStackTrace(cond)`) and returns a data frame with one +#' row for each stack frame and the columns `num` (stack frame number), +#' `call` (a function name or similar), and `loc` (source file path +#' and line number, if available). It was deprecated after shiny 1.0.5 because +#' it doesn't support deep stack traces. +#' @rdname stacktrace +#' @export +extractStackTrace <- function(calls, + full = get_devmode_option("shiny.fullstacktrace", FALSE), + offset = getOption("shiny.stacktraceoffset", TRUE)) { + + srcrefs <- getSrcRefs(calls) + if (offset) { + # Offset calls vs. srcrefs by 1 to make them more intuitive. + # E.g. for "foo [bar.R:10]", line 10 of bar.R will be part of + # the definition of foo(). + srcrefs <- c(utils::tail(srcrefs, -1), list(NULL)) + } + calls <- setSrcRefs(calls, srcrefs) + + callnames <- getCallNames(calls) + + # Hide and show parts of the callstack based on ..stacktrace(on|off).. + if (full) { + toShow <- rep.int(TRUE, length(calls)) + } else { + # Remove stop(), .handleSimpleError(), and h() calls from the end of + # the calls--they don't add any helpful information. But only remove + # the last *contiguous* block of them, and then, only if they are the + # last thing in the calls list. + hideable <- callnames %in% c("stop", ".handleSimpleError", "h") + # What's the last that *didn't* match stop/.handleSimpleError/h? + lastGoodCall <- max(which(!hideable)) + toRemove <- length(calls) - lastGoodCall + # But don't remove more than 5 levels--that's an indication we might + # have gotten it wrong, I guess + if (toRemove > 0 && toRemove < 5) { + calls <- utils::head(calls, -toRemove) + callnames <- utils::head(callnames, -toRemove) + } + + # This uses a ref-counting scheme. It might make sense to switch this + # to a toggling scheme, so the most recent ..stacktrace(on|off).. + # directive wins, regardless of what came before it. + # Also explicitly remove ..stacktraceon.. because it can appear with + # score > 0 but still should never be shown. + score <- rep.int(0, length(callnames)) + score[callnames == "..stacktraceoff.."] <- -1 + score[callnames == "..stacktraceon.."] <- 1 + toShow <- (1 + cumsum(score)) > 0 & !(callnames %in% c("..stacktraceon..", "..stacktraceoff..", "..stacktracefloor..")) + + # doTryCatch, tryCatchOne, and tryCatchList are not informative--they're + # just internals for tryCatch + toShow <- toShow & !(callnames %in% c("doTryCatch", "tryCatchOne", "tryCatchList")) + } + calls <- calls[toShow] + + calls <- rev(calls) # Show in traceback() order + index <- rev(which(toShow)) + width <- floor(log10(max(index))) + 1 + + data.frame( + num = index, + call = getCallNames(calls), + loc = getLocs(calls), + category = getCallCategories(calls), + stringsAsFactors = FALSE + ) +} + cleanLocs <- function(locs) { locs[!grepl("test-stacks\\.R", locs, perl = TRUE)] <- "" sub("^.*#", "", locs) diff --git a/tools/documentation/checkPkgdown.R b/tools/documentation/checkPkgdown.R index 75f9dfd644..744c6bb937 100644 --- a/tools/documentation/checkPkgdown.R +++ b/tools/documentation/checkPkgdown.R @@ -33,7 +33,7 @@ local({ # TODO .. or check that pkgdown::build_reference_index() does not produce warnings known_unindexed <- c("shiny-package", "stacktrace", "knitr_methods", "pageWithSidebar", "headerPanel", "shiny.appobj", - "deprecatedReactives", "reexports", "makeReactiveBinding", + "reexports", "makeReactiveBinding", "reactiveConsole", "registerThemeDependency", "memoryCache", "diskCache", "shinyDeprecated")