Module: Tailor::Rulers::IndentationSpacesRuler::AstXml

Included in:
ArgumentAlignment, LineContinuations
Defined in:
lib/tailor/rulers/indentation_spaces_ruler/ast_xml.rb

Overview

XXX: Reproducing the ast querying functions from foodcritic here. We either need to re-implement the queries not to rely on these functions or extract these functions to a shared gem.

Instance Method Summary collapse

Instance Method Details

#ast_hash_node?(node) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
# File 'lib/tailor/rulers/indentation_spaces_ruler/ast_xml.rb', line 43

def ast_hash_node?(node)
  node.first.respond_to?(:first) and node.first.first == :assoc_new
end

#ast_node_has_children?(node) ⇒ Boolean

Returns:

  • (Boolean)


47
48
49
# File 'lib/tailor/rulers/indentation_spaces_ruler/ast_xml.rb', line 47

def ast_node_has_children?(node)
  node.respond_to?(:first) and ! node.respond_to?(:match)
end

#build_xml(node, doc = nil, xml_node = nil) ⇒ Object



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
# File 'lib/tailor/rulers/indentation_spaces_ruler/ast_xml.rb', line 59

def build_xml(node, doc = nil, xml_node=nil)
  doc, xml_node = xml_document(doc, xml_node)

  if node.respond_to?(:each)
    # First child is the node name
    node.drop(1) if node.first.is_a?(Symbol)
    node.each do |child|
      if position_node?(child)
        xml_position_node(doc, xml_node, child)
      else
        if ast_node_has_children?(child)
          # The AST structure is different for hashes so we have to treat
          # them separately.
          if ast_hash_node?(child)
            xml_hash_node(doc, xml_node, child)
          else
            xml_array_node(doc, xml_node, child)
          end
        else
          xml_node['value'] = child.to_s unless child.nil?
        end
      end
    end
  end
  xml_node
end

#position_node?(node) ⇒ Boolean

If the provided node is the line / column information.

Returns:

  • (Boolean)


52
53
54
55
56
57
# File 'lib/tailor/rulers/indentation_spaces_ruler/ast_xml.rb', line 52

def position_node?(node)
  node.respond_to?(:length) and node.length == 2 and
  node.respond_to?(:all?) and node.all? do |child|
    child.respond_to?(:to_i)
  end
end

#xml_array_node(doc, xml_node, child) ⇒ Object



10
11
12
13
# File 'lib/tailor/rulers/indentation_spaces_ruler/ast_xml.rb', line 10

def xml_array_node(doc, xml_node, child)
  n = xml_create_node(doc, child)
  xml_node.add_child(build_xml(child, doc, n))
end

#xml_create_node(doc, c) ⇒ Object



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

def xml_create_node(doc, c)
  Nokogiri::XML::Node.new(c.first.to_s.gsub(/[^a-z_]/, ''), doc)
end

#xml_document(doc, xml_node) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/tailor/rulers/indentation_spaces_ruler/ast_xml.rb', line 19

def xml_document(doc, xml_node)
  if doc.nil?
    doc = Nokogiri::XML('<opt></opt>')
    xml_node = doc.root
  end
  [doc, xml_node]
end

#xml_hash_node(doc, xml_node, child) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/tailor/rulers/indentation_spaces_ruler/ast_xml.rb', line 27

def xml_hash_node(doc, xml_node, child)
  child.each do |c|
    n = xml_create_node(doc, c)
    c.drop(1).each do |a|
      xml_node.add_child(build_xml(a, doc, n))
    end
  end
end

#xml_position_node(doc, xml_node, child) ⇒ Object



36
37
38
39
40
41
# File 'lib/tailor/rulers/indentation_spaces_ruler/ast_xml.rb', line 36

def xml_position_node(doc, xml_node, child)
  pos = Nokogiri::XML::Node.new('pos', doc)
  pos['line'] = child.first.to_s
  pos['column'] = child[1].to_s
  xml_node.add_child(pos)
end