class Tailor::Rulers::IndentationSpacesRuler::ArgumentAlignment

Determines whether arguments spread across lines are correctly aligned.

Function calls with parentheses could be determined easily from the lexed line only but we need to support calls without parentheses too.

Public Class Methods

new(file_name) click to toggle source
# File lib/tailor/rulers/indentation_spaces_ruler/argument_alignment.rb, line 18
def initialize(file_name)
  @ast = build_xml(Ripper::SexpBuilder.new(File.read(file_name)).parse)
  @lex = Ripper.lex(File.read(file_name))
end

Public Instance Methods

expected_column(lineno, should_be_at) click to toggle source
# File lib/tailor/rulers/indentation_spaces_ruler/argument_alignment.rb, line 23
def expected_column(lineno, should_be_at)
  column = call_column(lineno) || declaration_column(lineno)
  correct_for_literals(lineno, column) || should_be_at
end

Private Instance Methods

call_column(lineno) click to toggle source
# File lib/tailor/rulers/indentation_spaces_ruler/argument_alignment.rb, line 40
def call_column(lineno)
  [
    first_argument(:command_call, :args_add_block, lineno),
    first_argument(:method_add_arg, :args_add_block, lineno)
  ].compact.min
end
correct_for_literals(lineno, column) click to toggle source

sexp column offsets for string literals do not include the quote

# File lib/tailor/rulers/indentation_spaces_ruler/argument_alignment.rb, line 31
def correct_for_literals(lineno, column)
  tstring_index = @lex.index do |pos, token|
    pos[0] == lineno and pos[1] == column and
      token == :on_tstring_content
  end

  tstring_index ? @lex[tstring_index -1][0][1] : column
end
declaration_column(lineno) click to toggle source
# File lib/tailor/rulers/indentation_spaces_ruler/argument_alignment.rb, line 47
def declaration_column(lineno)
  first_argument(:def, :params, lineno)
end
first_argument(parent, child, lineno) click to toggle source
# File lib/tailor/rulers/indentation_spaces_ruler/argument_alignment.rb, line 51
def first_argument(parent, child, lineno)
  method_defs = @ast.xpath("//#{parent}")
  method_defs.map do |d|
    d.xpath("descendant::#{child}[descendant::pos[@line = #{lineno}
      ]]/descendant::pos[position() = 1 and @line != #{lineno}]/
      @column").first.to_s.to_i
  end.reject { |c| c == 0 }.min
end