Skip to content

S7 method documentation links #4

@mduncans

Description

@mduncans

Hello, I'm really happy to see the new S7 support!

I have a package using S7 classes where I am trying to document some methods separately from the generic. I followed the new rd-S7 vignette and added this to my generic's roxygen comments:

#' Methods are available for the following classes:
#'
#' `r doclisting::methods_list("add_spec_columns")`

Running devtools::document() generated the following Rd content:

Methods are available for the following classes:

\itemize{
  \item \code{hyperion.tables::SummarySpec}
  \item \code{hyperion.tables::TableSpec}
}

so there was no link to the method's specific documentation. This also generated some warnings:

Warning messages:
1: In path.expand(path) : restarting interrupted promise evaluation

With Claude's help, I was able to trace this to pkgload:::dev_topic_parse. The doclisting::methods_list() call generates a method alias of the form "add_spec_columns,hyperion.tables::TableSpec-method", which gets parsed as:

> pkgload:::dev_topic_parse("add_spec_columns,hyperion.tables::TableSpec-method")
$topic
[1] "TableSpec-method"

$pkg_names
[1] "add_spec_columns,hyperion.tables"

It looks like dev_topic_parse is splitting on :: and treating the first piece as a package name. For the S7 method aliases in my case, the class name itself is fully qualified (pkg::Class), so :: appears embedded inside the topic. The resulting pkg_names doesn't correspond to a real package, which I think is what cascades into the warnings I was seeing, and ultimately to doclisting not finding a help topic.

Locally I patched dev_topic_parse to only split on :: when the prefix is
actually a loaded dev package:

dev_topic_parse <- function(topic, dev_packages = NULL) {
  stopifnot(is_string(topic))

  pkgs <- dev_packages %||% dev_packages()

  pieces <- strsplit(topic, ":::?")[[1]]
  # Only treat as `pkg::topic` when the prefix is a loaded dev package.
  # Otherwise `::` is part of the topic itself (e.g., S7/S4 method aliases
  # like "generic,pkg::Class-method" where `pkg::Class` is the class name).
  if (length(pieces) > 1 && pieces[1] %in% pkgs) {
    pkgs <- pieces[1]
    topic <- pieces[2]
  }

  list(
    topic = topic,
    pkg_names = pkgs
  )
}

With that change the generated Rd correctly contains links:

Methods are available for the following classes:

\itemize{
  \item \code{\link[=add_spec_columns-hyperion.tables-SummarySpec-method]{hyperion.tables::SummarySpec}}
  \item \code{\link[=add_spec_columns-hyperion.tables-TableSpec-method]{hyperion.tables::TableSpec}}
}

Let me know if you'd like a reprex or to move this issue to a different package.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions