class ActionView::Template::Handlers::ERB
def find_offset(compiled, source_tokens, error_column)
the current token from looping past the next token if they both
a match for the current token has been found. This is to prevent
Prioritize matching the next token over the current token once
c. Otherwise: Advance 1 byte
b. If A: test error_column or advance scanner.
a. If B: start over with next token set (B, C).
2. Find a match for B or A:
1. Find a match for A: test error_column or advance scanner.
For example, if we want to find tokens A, B, C, we do the following:
a match of the first token before matching either token.
Iterate consecutive pairs of CODE or TEXT tokens, requiring
original source template.
contains the error_column, then return the offset compared to the
Find which token in the source template spans the byte range that
def find_offset(compiled, source_tokens, error_column) compiled = StringScanner.new(compiled) offset_source_tokens(source_tokens).each_cons(2) do |(name, str, offset), (_, next_str, _)| matched_str = false until compiled.eos? if matched_str && next_str && compiled.match?(next_str) break elsif compiled.match?(str) matched_str = true if name == :CODE && compiled.pos <= error_column && compiled.pos + str.bytesize >= error_column return compiled.pos - offset end compiled.pos += str.bytesize else compiled.pos += 1 end end end raise LocationParsingError, "Couldn't find code snippet" end