Module: Repper::Codemod
- Defined in:
- lib/repper/codemod.rb
Overview
Formatter for Ruby code containing Regexp literals
Defined Under Namespace
Classes: Location
Class Method Summary collapse
Class Method Details
.call(code) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/repper/codemod.rb', line 6 def call(code) formatted_code = code.dup regexp_locations(code).reverse.each do |loc| beg_idx = code[/\A(.*\n){#{loc.beg_line}}/].size + loc.beg_char end_idx = code[/\A(.*\n){#{loc.end_line}}/].size + loc.end_char range = beg_idx..end_idx /\A(?<start>\/|%r.)(?<source>.*)(?<stop>[^a-z])(?<flags>[a-z]*)\z/m =~ code[range] tokens = Tokenizer.call(source, delimiters: [start, stop], flags: flags) formatted_regexp = Format::Extended.call(tokens, Theme::Plain) # indent consistently by applying leading line indentation to all lines lead_indentation = code.lines[loc.beg_line][/^ */] formatted_regexp.gsub!("\n", "\n#{lead_indentation}") formatted_code[range] = formatted_regexp end formatted_code end |
.regexp_locations(code) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/repper/codemod.rb', line 32 def regexp_locations(code) = 0 beg_tokens = {} Ripper.lex(code).each.with_object([]) do |token, acc| case token[1] when :on_regexp_beg beg_tokens[] = token # nested regexp literals are not supported a.t.m., so if we're # in an embed, discard the location of the surrounding regexp. beg_tokens[ - 1] = nil when :on_regexp_end next unless beg_token = beg_tokens[] acc << Location.new( beg_line: beg_token[0][0] - 1, # note: using 0-indexed line values beg_char: beg_token[0][1], end_line: token[0][0] - 1, end_char: token[0][1] + (token[2].length - 1), # lex includes flags ) when :on_embexpr_beg # embedded expression a.k.a. interpolation (#{...}) += 1 when :on_embexpr_end -= 1 when :on_const, :on_ident # OK when embedded - Regexp::Parser will treat them as literals else # other embedded expressions are not supported beg_tokens[ - 1] = nil end end end |