Skip to content

Commit ab9f7e8

Browse files
only replace text of strings if necessary
fix misnomer of `verify_str_txt()`, better variable names within this function, outsource identification of insufficiently parsed strings in identify_insufficiently_parsed_stings(), add line and col check.
1 parent 9aef2b1 commit ab9f7e8

File tree

4 files changed

+91
-25
lines changed

4 files changed

+91
-25
lines changed

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ importFrom(purrr,flatten_chr)
2121
importFrom(purrr,flatten_int)
2222
importFrom(purrr,map)
2323
importFrom(purrr,map2)
24+
importFrom(purrr,map2_lgl)
2425
importFrom(purrr,map_chr)
2526
importFrom(purrr,map_lgl)
2627
importFrom(purrr,partial)

R/parse.R

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#' @keywords internal
1818
tokenize <- function(text) {
1919
get_parse_data(text, include_text = NA) %>%
20-
verify_str_txt(text) %>%
20+
ensure_correct_str_txt(text) %>%
2121
enhance_mapping_special()
2222
}
2323

@@ -49,33 +49,77 @@ add_id_and_short <- function(pd) {
4949
}
5050

5151

52-
#' Verify the text of strings
52+
#' Ensure a correct `text` of all strings
5353
#'
5454
#' Make sure `text` of the tokens `STR_CONST` is correct and adapt if necessary.
5555
#' We first parse `text` again and include also non-terminal text. Then, we
5656
#' replace offending `text` in the terminal expressions with the text of their
57-
#' parents.
58-
#' @param pd_with_terminal_text A parse table.
59-
#' @param text The text from which `pd_with_terminal_text` was created. Needed
57+
#' parents if their line / col position matches and return an error otherwise.
58+
#' @param pd A parse table.
59+
#' @param text The text from which `pd` was created. Needed
6060
#' for potential reparsing.
6161
#' @keywords internal
62-
verify_str_txt <- function(pd_with_terminal_text, text) {
63-
string_ind <- pd_with_terminal_text$token == "STR_CONST"
64-
strings <- pd_with_terminal_text[string_ind, ]
65-
parent_of_strings_ind <- pd_with_terminal_text$id %in% strings$parent
66-
other_ind <- !(string_ind | parent_of_strings_ind)
67-
if (nrow(strings) == 0 || !any(substr(strings$text, 1, 1) == "[")) {
68-
return(pd_with_terminal_text)
62+
ensure_correct_str_txt <- function(pd, text) {
63+
is_problematic_string <- identify_insufficiently_parsed_stings(pd, text)
64+
problematic_strings <- pd[is_problematic_string, ]
65+
is_parent_of_problematic_string <-
66+
pd$id %in% problematic_strings$parent
67+
68+
is_unaffected_token <- !(is_problematic_string | is_parent_of_problematic_string)
69+
if (!any(is_problematic_string)) {
70+
return(pd)
6971
}
72+
7073
pd_with_all_text <- get_parse_data(text, include_text = TRUE)
71-
parent_of_strings <- pd_with_all_text[parent_of_strings_ind, c("id", "text", "short")]
72-
strings$text <- NULL
73-
strings$short <- NULL
74-
new_strings <- merge(strings, parent_of_strings, by.x = "parent", by.y = "id")
74+
parent_cols_for_merge <- c("id", "text", "short", line_col_names())
75+
parent_of_problematic_strings <-
76+
pd_with_all_text[is_parent_of_problematic_string, parent_cols_for_merge]
77+
problematic_strings$text <- NULL
78+
problematic_strings$short <- NULL
79+
new_strings <- merge(problematic_strings, parent_of_problematic_strings,
80+
by.x = "parent", by.y = "id"
81+
) %>%
82+
as_tibble()
83+
84+
if (!lines_and_cols_match(new_strings)) {
85+
stop(paste(
86+
"Error in styler:::ensure_correct_str_txt().",
87+
"Please file an issue on GitHub (https://github.com/r-lib/styler/issues)",
88+
), call. = FALSE)
89+
}
7590
bind_rows(
7691
new_strings,
77-
pd_with_terminal_text[other_ind, ],
78-
pd_with_terminal_text[parent_of_strings_ind, ]
92+
pd[is_unaffected_token, ],
93+
pd[is_parent_of_problematic_string, ]
7994
) %>%
8095
arrange(pos_id)
8196
}
97+
98+
#' Indentify strings that were not fully parsed
99+
#'
100+
#' Indentifies strings that were not fully parsed due to their vast length.
101+
#' @details
102+
#' The meaning of the variable `is_problematic_string` in the source code
103+
#' changes from "all strings" to "all problematic strings", is partly
104+
#' missleading and this approach was choosen for performance reasons only.
105+
#' @param pd A parse table.
106+
#' @param text The initial code to style.
107+
identify_insufficiently_parsed_stings <- function(pd, text) {
108+
is_problematic_string <- pd$token == "STR_CONST"
109+
candidate_substring <- substr(
110+
pd$text[is_problematic_string], 1, 1
111+
)
112+
is_problematic_string[is_problematic_string] <- candidate_substring == "["
113+
is_problematic_string
114+
}
115+
116+
#' @importFrom purrr map2_lgl
117+
lines_and_cols_match <- function(data) {
118+
left <- paste0(line_col_names(), ".x")
119+
right <- paste0(line_col_names(), ".y")
120+
map2_lgl(left, right,
121+
two_cols_match,
122+
data = data
123+
) %>%
124+
all()
125+
}

man/verify_str_txt.Rd renamed to man/ensure_correct_str_txt.Rd

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/identify_insufficiently_parsed_stings.Rd

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)