Class: Ricecream::Analyzer

Inherits:
Ripper
  • Object
show all
Defined in:
lib/ricecream/analyzer.rb

Constant Summary collapse

MethodName =
/\A(?:ic|ic_format|p)\z/

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Analyzer

Returns a new instance of Analyzer.



10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/ricecream/analyzer.rb', line 10

def initialize(path)
  @ic_methods = []
  @last_loc = [1, 0]
  @path = File.absolute_path(path.to_s)
  return unless File.file?(@path)
  @script = File.binread(@path) + " "
  super(@script, @path)
  parse
  enc = encoding
  enc = Encoding::UTF_8 if enc == Encoding::ASCII_8BIT
  @script.force_encoding(enc)
  @script_lines = @script.lines
end

Instance Method Details

#add_method_data(name, line, col1, col2, args_add) ⇒ Object



101
102
103
104
105
106
107
108
109
110
# File 'lib/ricecream/analyzer.rb', line 101

def add_method_data(name, line, col1, col2, args_add)
  locs = []
  while args_add
    break unless args_add.dig(0, 0) == :args_add
    locs.unshift args_add.dig(0, 1)
    args_add = args_add.dig(1)
  end
  locs.unshift [line, col2]
  @ic_methods.push({ name: name.to_sym, lineno: line, column: col1, locs: locs })
end

#byteslice(from, to) ⇒ Object



33
34
35
36
37
38
39
40
41
# File 'lib/ricecream/analyzer.rb', line 33

def byteslice(from, to)
  return @script_lines[from[0] - 1].byteslice(from[1]...to[1]) if from[0] == to[0]

  str = @script_lines[from[0] - 1][from[1]...-1]
  (from[0]...(to[0] - 1)).each do |i|
    str += @script_lines[i]
  end
  str += @script_lines[to[0] - 1].byteslice(0...to[1])
end

#ic_methodsObject



24
25
26
27
28
29
30
31
# File 'lib/ricecream/analyzer.rb', line 24

def ic_methods
  @ic_methods.select { |ic| ic[:locs].size > 1 }.map do |ic|
    args = ic[:locs].each_cons(2).map do |locs|
      byteslice(locs[0], locs[1]).delete_prefix(",").strip.gsub(/\R+/, " ")
    end
    ICMethod.new(ic[:name], @path, ic[:lineno], ic[:column], args.size, args)
  end
end

#on_command(*args) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ricecream/analyzer.rb', line 62

def on_command(*args)
  args.unshift [:command, @last_loc]
  return args unless args.dig(1, 0) == :@ident
  method_name = args.dig(1, 1)
  if MethodName === method_name
    line = args.dig(1, 2, 0)
    col1 = args.dig(1, 2, 1)
    col2 = col1 + args.dig(1, 1).length
    add_method_data(method_name, line, col1, col2, args.dig(2, 1))
  end
  args
end

#on_method_add_arg(*args) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/ricecream/analyzer.rb', line 88

def on_method_add_arg(*args)
  args.unshift [:method_add_arg, @last_loc]
  return args unless args.dig(1, 0, 0) == :fcall && args.dig(1, 1, 0) == :@ident
  method_name = args.dig(1, 1, 1)
  if MethodName === method_name
    line = args.dig(1, 1, 2, 0)
    col1 = args.dig(1, 1, 2, 1)
    col2 = col1 + args.dig(1, 1, 1).length + 1
    add_method_data(method_name, line, col1, col2, args.dig(2, 1, 1))
  end
  args
end

#on_vcall(*args) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ricecream/analyzer.rb', line 75

def on_vcall(*args)
  args.unshift [:vcall, @last_loc]
  return args unless args.dig(1, 0) == :@ident
  method_name = args.dig(1, 1)
  if MethodName === method_name
    line = args.dig(1, 2, 0)
    col1 = args.dig(1, 2, 1)
    col2 = col1 + args.dig(1, 1).length
    add_method_data(method_name, line, col1, col2, args.dig(2, 1, 1))
  end
  args
end