class RailsRouteChecker::Parsers::HamlParser::RubyExtractor

Constants

LOOP_KEYWORDS
MID_BLOCK_KEYWORDS
RubySource
START_BLOCK_KEYWORDS

Attributes

document[R]

Public Class Methods

extract(document) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 9
def self.extract(document)
  new(document).extract
end
new(document) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 13
def initialize(document)
  @document = document
end

Public Instance Methods

extract() click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 17
def extract
  @source_lines = []
  @source_map = {}
  @line_count = 0
  @indent_level = 0
  @output_count = 0

  visit_children(document.tree)

  RubySource.new(@source_lines.join("\n"), @source_map)
end
visit(node) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 71
def visit(node)
  block_called = false

  block = lambda do |descend = :children|
    block_called = true
    visit_children(node) if descend == :children
  end

  case node.type
  when :tag
    visit_tag(node)
  when :script, :silent_script
    visit_script(node, &block)
  when :filter
    visit_filter(node)
  end

  visit_children(node) unless block_called
end
visit_children(parent) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 91
def visit_children(parent)
  parent.children.each { |node| visit(node) }
end
visit_filter(node) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 63
def visit_filter(node)
  return unless node.filter_type == 'ruby'

  node.text.split("\n").each_with_index do |line, index|
    add_line(line, node.line + index + 1, false)
  end
end
visit_script(node) { || ... } click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 47
def visit_script(node)
  code = node.text
  add_line(code.strip, node)

  start_block = anonymous_block?(code) || start_block_keyword?(code)

  @indent_level += 1 if start_block

  yield

  return unless start_block

  @indent_level -= 1
  add_line('end', node)
end
visit_tag(node) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 29
def visit_tag(node)
  additional_attributes = node.dynamic_attributes_sources

  additional_attributes.each do |attributes_code|
    attributes_code = attributes_code.gsub(/\s*\n\s*/, ' ').strip
    add_line("{}.merge(#{attributes_code.strip})", node)
  end

  if node.hash_attributes? && node.dynamic_attributes_sources.empty?
    normalized_attr_source = node.dynamic_attributes_source[:hash].gsub(/\s*\n\s*/, ' ')

    add_line(normalized_attr_source, node)
  end

  code = node.script.strip
  add_line(code, node) unless code.empty?
end

Private Instance Methods

add_line(code, node_or_line, discard_blanks = true) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 99
def add_line(code, node_or_line, discard_blanks = true)
  return if code.empty? && discard_blanks

  indent_level = @indent_level

  if node_or_line.respond_to?(:line)
    indent_level -= 1 if mid_block_keyword?(code)
  end

  indent = (' ' * 2 * indent_level)

  @source_lines << indent_code(code, indent)

  original_line =
    node_or_line.respond_to?(:line) ? node_or_line.line : node_or_line

  (code.count("\n") + 1).times do
    @line_count += 1
    @source_map[@line_count] = original_line
  end
end
anonymous_block?(text) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 126
def anonymous_block?(text)
  text =~ /\bdo\s*(\|\s*[^\|]*\s*\|)?(\s*#.*)?\z/
end
block_keyword(text) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 141
def block_keyword(text)
  # Need to handle 'for'/'while' since regex stolen from HAML parser doesn't
  keyword = text[/\A\s*([^\s]+)\s+/, 1]
  return keyword if keyword && LOOP_KEYWORDS.include?(keyword)

  keyword = text.scan(Haml::Parser::BLOCK_KEYWORD_REGEX)[0]
  return unless keyword

  keyword[0] || keyword[1]
end
indent_code(code, indent) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 121
def indent_code(code, indent)
  codes = code.split("\n")
  codes.map { |c| indent + c }.join("\n")
end
mid_block_keyword?(text) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 136
def mid_block_keyword?(text)
  MID_BLOCK_KEYWORDS.include?(block_keyword(text))
end
start_block_keyword?(text) click to toggle source
# File lib/rails-route-checker/parsers/haml_parser/ruby_extractor.rb, line 131
def start_block_keyword?(text)
  START_BLOCK_KEYWORDS.include?(block_keyword(text))
end