Skip to content

Commit

Permalink
split_on_line_directives: fix handling of single-file package case
Browse files Browse the repository at this point in the history
split_on_line_directives breaks the input at #line directives and
returns a named list of lines for each file.

For a package with a single file under R/, there is one directive.
The bounds calculation is still correct for that case.  However, the
return value is incorrectly a matrix rather than a list because the
mapply call simplifies the result.

At this point, this bug is mostly [*] unexposed because this code path
is only triggered if utils::getParseData returns NULL, and it should
always return a non-NULL result for the single-file package case.  The
next commit will reorder things, exposing the bug.

Tell mapply to not simplify the result.

[*] The simplification to a matrix could also happen for multi-file
    packages in the unlikely event that all files have the same number
    of lines.
  • Loading branch information
kyleam committed Nov 15, 2024
1 parent 051c41d commit 2b7c432
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
7 changes: 6 additions & 1 deletion R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,12 @@ split_on_line_directives <- function(lines) {

file_starts <- directive_lines + 1
file_ends <- c(directive_lines[-1] - 1, length(lines))
res <- mapply(function(start, end) lines[start:end], file_starts, file_ends)
res <- mapply(
function(start, end) lines[start:end],
file_starts,
file_ends,
SIMPLIFY = FALSE
)
names(res) <- na.omit(matches$filename)
res
}
Expand Down
31 changes: 31 additions & 0 deletions tests/testthat/test-utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,34 @@ test_that("split_on_line_directives returns NULL for input without directive (#5
NULL
)
})

test_that("split_on_line_directives does not simplify the result (#588)", {
expect_identical(
split_on_line_directives(
c(
'#line 1 "foo.R"',
"abc",
"def"
)
),
list(
"foo.R" = c("abc", "def")
)
)
expect_identical(
split_on_line_directives(
c(
'#line 1 "foo.R"',
"abc",
"def",
'#line 4 "bar.R"',
"ghi",
"jkl"
)
),
list(
"foo.R" = c("abc", "def"),
"bar.R" = c("ghi", "jkl")
)
)
})

0 comments on commit 2b7c432

Please sign in to comment.