Skip to content

Commit 5ab2280

Browse files
committed
parse_data: promote custom parse logic for R 4.4 compatibility
utils::getParseData has a longstanding bug: for an installed package, parse data is available only for the last file [1]. To work around that, the get_tokens helper first calls getParseData and then falls back to custom logic that extracts the concatenated source lines, splits them on #line directives, and calls getParseData on each file's lines. The getParseData bug was fixed in R 4.4.0 (r84538). Unfortunately that change causes at least two issues (for some subset of packages): a substantial performance regression [2] and an error when applying exclusions [3]. Under R 4.4, getParseData always returns non-NULL as a result of that change when calculating package coverage (in other words, the get_parse_data fallback is _not_ triggered). The slowdown is partially due to the parse data no longer being cached across get_tokens calls. Another relevant aspect, for both the slowdown and the error applying exclusions, is likely that the new getParseData returns data for the entire package rather than the per-file parse data the downstream covr code expects. One solution would be to adapt covr's caching and handling of the getParseData when running under R 4.4.0 or later. Instead go with a simpler and more minimal fix. Reorder the calls so that the get_parse_data call, which we know has been the primary code path for package coverage before R 4.4.0, is the first call tried. Leave getParseData as the fallback to handle the non-package coverage cases. [1] r-lib#154 https://bugs.r-project.org/show_bug.cgi?id=16756 [2] As an extreme case, calling package_coverage on R.utils goes from under 15 minutes to over 6 hours. [3] nanotime (v0.3.10) and diffobj (v0.3.5) are two examples of packages that hit into this error. Closes r-lib#576 Closes r-lib#579 Re: r-lib#567
1 parent 2b7c432 commit 5ab2280

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# covr (development version)
22

3+
* Fixed a performance regression and an error triggered by a change in R
4+
4.4.0. (@kyleam, #588)
5+
36
* Fixed an issue where attempting to generate code coverage on an already-loaded
47
package could fail on Windows. (@kevinushey, #574)
58

R/parse_data.R

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,16 @@ clean_parse_data <- function() {
140140
rm(list = ls(package_parse_data), envir = package_parse_data)
141141
}
142142

143-
# Needed to work around https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=16756
144143
get_tokens <- function(srcref) {
145-
getParseData(srcref) %||% get_parse_data(attr(getSrcref(srcref), "srcfile"))
144+
# Before R 4.4.0, covr's custom get_parse_data is necessary because
145+
# utils::getParseData returns parse data for only the last file in the
146+
# package. That issue (bug#16756) is fixed in R 4.4.0 (r84538).
147+
#
148+
# On R 4.4.0, continue to use get_parse_data because covr's code expects the
149+
# result to be limited to the srcref file. getParseData will return parse data
150+
# for all of the package's files.
151+
get_parse_data(attr(getSrcref(srcref), "srcfile")) %||%
152+
# This covers the non-installed file case where the source file isn't a
153+
# concatenated file with "line N" directives.
154+
getParseData(srcref)
146155
}

0 commit comments

Comments
 (0)