Class: Parser::Runner::RubyParse::LocationProcessor

Inherits:
AST::Processor
  • Object
show all
Defined in:
lib/parser/runner/ruby_parse.rb

Instance Method Summary collapse

Methods inherited from AST::Processor

#on_argument, #on_case, #on_cdecl, #on_class, #on_const, #on_def, #on_defs, #on_if, #on_op_asgn, #on_resbody, #on_rescue, #on_send, #on_var, #on_vasgn, #process_argument_node, #process_regular_node, #process_var_asgn_node, #process_variable_node

Instance Method Details

#process(node) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/parser/runner/ruby_parse.rb', line 9

def process(node)
  p node

  if node.src.nil?
    puts "\e[31m[no location info]\e[0m"
  elsif node.src.expression.nil?
    puts "\e[31m[location info present but empty]\e[0m"
  else
    source_line_no = nil
    source_line    = ""
    hilight_line   = ""

    print_line = lambda do
      unless hilight_line.empty?
        puts hilight_line.
          gsub(/[a-z_]+/) { |m| "\e[1;33m#{m}\e[0m" }.
          gsub(/[~.]+/)   { |m| "\e[1;35m#{m}\e[0m" }
        hilight_line = ""
      end
    end

    print_source = lambda do |range|
      source_line = range.source_line
      puts "\e[32m#{source_line}\e[0m"
      source_line
    end

    node.src.to_hash.
      sort_by do |name, range|
        [(range ? range.line : 0),
         (name == :expression ? 1 : 0)]
      end.
      each do |name, range|
        next if range.nil?

        if source_line_no != range.line
          print_line.call()
          source_line    = print_source.call(range)
          source_line_no = range.line
        end

        beg_col = range.begin.column

        if beg_col + range.length > source_line.length
          multiline    = true
          range_length = source_line.length - beg_col + 3
        else
          multiline    = false
          range_length = range.length
        end

        length  = range_length + 1 + name.length
        end_col = beg_col + length

        if beg_col > 0
          col_range = (beg_col - 1)...end_col
        else
          col_range = beg_col...end_col
        end

        if hilight_line.length < end_col
          hilight_line = hilight_line.ljust(end_col)
        end

        if hilight_line[col_range] =~ /^\s*$/
          if multiline
            tail = ('~' * (source_line.length - beg_col)) + '...'
          else
            tail = '~' * range_length
          end

          tail = ' ' + tail if beg_col > 0

          hilight_line[col_range] = tail + " #{name}"
        else
          print_line.call
          redo
        end
      end

    print_line.call
  end

  super
end