Class: Tailor::Rulers::IndentationSpacesRuler::LineContinuations

Inherits:
Object
  • Object
show all
Includes:
AstXml
Defined in:
lib/tailor/rulers/indentation_spaces_ruler/line_continuations.rb

Overview

Determines whether a line is a continuation of previous lines. For ease of implementation we use the s-exp support in Ripper, rather than trying to work it out solely from the token events on the ruler.

Instance Method Summary collapse

Methods included from AstXml

#ast_hash_node?, #ast_node_has_children?, #build_xml, #position_node?, #xml_array_node, #xml_create_node, #xml_document, #xml_hash_node, #xml_position_node

Constructor Details

#initialize(file_name) ⇒ LineContinuations

Returns a new instance of LineContinuations.



15
16
17
# File 'lib/tailor/rulers/indentation_spaces_ruler/line_continuations.rb', line 15

def initialize(file_name)
  @ast = build_xml(Ripper::SexpBuilder.new(File.read(file_name)).parse)
end

Instance Method Details

#line_has_nested_statements?(lineno) ⇒ Boolean

Are there statements further nested below this line?

Returns:

  • (Boolean)


40
41
42
43
44
# File 'lib/tailor/rulers/indentation_spaces_ruler/line_continuations.rb', line 40

def line_has_nested_statements?(lineno)
  @ast.xpath("//pos[@line='#{lineno}']/
    ancestor::*[parent::stmts_add][1]/
    descendant::stmts_add[descendant::pos[@line > #{lineno}]]").any?
end

#line_is_continuation?(lineno) ⇒ Boolean

Is the specified line actually a previous line continuing?

Returns:

  • (Boolean)


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/tailor/rulers/indentation_spaces_ruler/line_continuations.rb', line 20

def line_is_continuation?(lineno)
  @continuations ||= begin
    statements = @ast.xpath('//stmts_add/*[
      preceding-sibling::stmts_new | preceding-sibling::stmts_add]')
    statements.reject do |stmt|
      s = stmt.xpath('ancestor::stmts_add').size
      stmt.xpath("descendant::pos[count(ancestor::stmts_add) = #{s}]/
        @line").map { |s| s.to_s.to_i }.uniq.size < 2
    end.reject { |stmt| stmt.name == 'case' }.map do |stmt|
      lines_nesting = lines_with_nesting_level(stmt)
      lines_nesting.shift
      min_level = lines_nesting.values.min
      lines_nesting.reject { |_, n| n > min_level }.keys
    end.flatten
  end

  @continuations.include?(lineno)
end