class I18n::Tasks::Scanners::LocalRubyParser

Constants

BLOCK_EXPR

ignore_blocks feature inspired by shopify/better-html github.com/Shopify/better-html/blob/087943ffd2a5877fa977d71532010b0c91239519/lib/better_html/test_helper/ruby_node.rb#L24

Public Class Methods

new(ignore_blocks: false) click to toggle source
# File lib/i18n/tasks/scanners/local_ruby_parser.rb, line 11
def initialize(ignore_blocks: false)
  @parser = ::Parser::CurrentRuby.new
  @ignore_blocks = ignore_blocks
end

Public Instance Methods

normalize_comment_location(comment, location) click to toggle source

Normalize location for comment

@param comment {Parser::Source::Comment} A comment with local location @param location {Parser::Source::Map} Global location for the parsed string @return {Parser::Source::Comment}

# File lib/i18n/tasks/scanners/local_ruby_parser.rb, line 76
def normalize_comment_location(comment, location)
  range = ::Parser::Source::Range.new(
    location.expression.source_buffer,
    location.expression.to_range.begin + comment.location.expression.to_range.begin,
    location.expression.to_range.begin + comment.location.expression.to_range.end
  )
  ::Parser::Source::Comment.new(range)
end
normalize_location(node, location) click to toggle source

@param node {Parser::AST::Node} Node in parsed code @param location {Parser::Source::Map} Global location for the parsed string @return {Parser::AST::Node}

# File lib/i18n/tasks/scanners/local_ruby_parser.rb, line 37
def normalize_location(node, location)
  return node.map { |child| normalize_location(child, location) } if node.is_a?(Array)

  return node unless node.is_a?(::Parser::AST::Node)

  node.updated(
    nil,
    node.children.map { |child| normalize_location(child, location) },
    { location: updated_location(location, node.location) }
  )
end
parse(source, location: nil) click to toggle source

Parse string and normalize location

# File lib/i18n/tasks/scanners/local_ruby_parser.rb, line 17
def parse(source, location: nil)
  buffer = ::Parser::Source::Buffer.new('(string)')
  buffer.source = if @ignore_blocks
                    source.sub(BLOCK_EXPR, '')
                  else
                    source
                  end

  @parser.reset
  ast, comments = @parser.parse_with_comments(buffer)
  ast = normalize_location(ast, location)
  comments = comments.map { |comment| normalize_comment_location(comment, location) }
  [ast, comments]
end
updated_location(global_location, local_location) click to toggle source

Calculate location relative to a global location

@param global_location {Parser::Source::Map} Global location where the code was parsed @param local_location {Parser::Source::Map} Local location in the parsed string @return {Parser::Source::Map}

# File lib/i18n/tasks/scanners/local_ruby_parser.rb, line 54
def updated_location(global_location, local_location)
  return global_location if local_location.expression.nil?

  range = ::Parser::Source::Range.new(
    global_location.expression.source_buffer,
    global_location.expression.to_range.begin + local_location.expression.to_range.begin,
    global_location.expression.to_range.begin + local_location.expression.to_range.end
  )

  ::Parser::Source::Map::Definition.new(
    range.begin,
    range.begin,
    range.begin,
    range.end
  )
end