Class: M::FinishLine

Inherits:
Ripper
  • Object
show all
Defined in:
lib/m/finish_line.rb

Overview

Stripped down parser that can determine the ending line for a method.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeFinishLine

Returns a new instance of FinishLine.



15
16
17
18
19
# File 'lib/m/finish_line.rb', line 15

def initialize(*)
  # A hash mapping the 1-indexed line numbers that tests start on to where they end.
  @begins_to_ends = {}
  super
end

Class Method Details

.ending_line_for(method_obj) ⇒ Object

Helper to translate a method object into the path and line range where the method was defined.



10
11
12
13
# File 'lib/m/finish_line.rb', line 10

def self.ending_line_for(method_obj)
  path, begin_line = method_obj.source_location
  new(File.read(path), path).parse[begin_line]
end

Instance Method Details

#first_arg(arg) ⇒ Object Also known as: on_method_add_arg, on_command, on_stmts_add, on_arg_paren, on_bodystmt



52
53
54
# File 'lib/m/finish_line.rb', line 52

def first_arg(arg, *)
  arg
end

#just_linenoObject Also known as: on_ident, on_do_block, on_stmts_new, on_brace_block



56
57
58
# File 'lib/m/finish_line.rb', line 56

def just_lineno(*)
  lineno
end

#on_args_add(parts, part) ⇒ Object



75
76
77
# File 'lib/m/finish_line.rb', line 75

def on_args_add(parts, part)
  parts << part
end

#on_args_add_block(args, *rest) ⇒ Object



79
80
81
# File 'lib/m/finish_line.rb', line 79

def on_args_add_block(args, *rest)
  args.first
end

#on_args_newObject



71
72
73
# File 'lib/m/finish_line.rb', line 71

def on_args_new
  []
end

#on_command_call(begin_lineno, _args) ⇒ Object



48
49
50
# File 'lib/m/finish_line.rb', line 48

def on_command_call(*, begin_lineno, _args)
  begin_lineno
end

#on_def(begin_line) ⇒ Object

method test e.g. ‘def test_some_description` This event’s first argument gets the ident node containing the method name, which we have overridden to return the line number of the ident instead.



30
31
32
# File 'lib/m/finish_line.rb', line 30

def on_def(begin_line, *)
  @begins_to_ends[begin_line] = lineno
end

#on_method_add_block(begin_line, end_line) ⇒ Object

Everything past this point is to support declarative tests, which require more work to get right because of the many different ways methods can be invoked in ruby, all of which are parsed differently.

The approach is just to store the current line number when the “test” method is called and pass it up the tree so it’s available at the point when we also know the line where the associated block ends.



42
43
44
45
46
# File 'lib/m/finish_line.rb', line 42

def on_method_add_block(begin_line, end_line)
  if begin_line && end_line
    @begins_to_ends[begin_line] = end_line
  end
end

#parseObject



21
22
23
24
# File 'lib/m/finish_line.rb', line 21

def parse
  super
  @begins_to_ends
end