class Transpec::DynamicAnalyzer::Rewriter

Constants

EVAL_TARGET_TYPES

Public Instance Methods

clear_requests!() click to toggle source
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 31
def clear_requests!
  @requests = nil
end
process(ast, source_rewriter) click to toggle source
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 18
def process(ast, source_rewriter)
  # TODO: Currently multitheading is not considered...
  clear_requests!
  collect_requests(ast)
  process_requests(source_rewriter)
end
register_request(node, key, instance_eval_string, eval_target_type = :object) click to toggle source
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 35
def register_request(node, key, instance_eval_string, eval_target_type = :object)
  unless EVAL_TARGET_TYPES.include?(eval_target_type)
    fail "Target type must be any of #{EVAL_TARGET_TYPES}"
  end

  requests[node] ||= {}
  requests[node][key] = [eval_target_type, instance_eval_string]
end
requests() click to toggle source
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 25
def requests
  # AST::Node#eql? returns true if two nodes have the same structure,
  # even if they are not identical objects.
  @requests ||= {}.compare_by_identity
end

Private Instance Methods

build_wrapper_codes(node, analysis_codes) click to toggle source
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 82
def build_wrapper_codes(node, analysis_codes)
  forward = "#{ANALYSIS_MODULE}.#{ANALYSIS_METHOD}(("
  backward = format('), self, %s, %s)', node_id(node).inspect, hash_literal(analysis_codes))
  [forward, backward]
end
collect_requests(ast) click to toggle source
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 46
def collect_requests(ast)
  return unless ast

  ast.each_node do |node|
    Syntax.standalone_syntaxes.each do |syntax_class|
      syntax = syntax_class.new(node)
      collect_requests_of_syntax(syntax)
    end
  end
end
collect_requests_of_syntax(syntax) click to toggle source
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 57
def collect_requests_of_syntax(syntax)
  return unless syntax.dynamic_analysis_target?
  syntax.register_dynamic_analysis_request(self)
  syntax.dependent_syntaxes.each do |dependent_syntax|
    collect_requests_of_syntax(dependent_syntax)
  end
end
hash_literal(hash) click to toggle source

Hash#inspect generates invalid literal with following example:

> eval({ :predicate? => 1 }.inspect) SyntaxError: (eval):1: syntax error, unexpected => {:predicate?=>1}

^
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 94
def hash_literal(hash)
  literal = '{ '

  hash.each_with_index do |(key, value), index|
    literal << ', ' unless index.zero?
    literal << "#{key.inspect} => #{value.inspect}"
  end

  literal << ' }'
end
inject_analysis_code(node, analysis_codes, source_rewriter) click to toggle source
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 71
def inject_analysis_code(node, analysis_codes, source_rewriter)
  source_range = if (block_node = block_node_taken_by_method(node))
                   block_node.loc.expression
                 else
                   node.loc.expression
                 end

  forward, backward = build_wrapper_codes(node, analysis_codes)
  source_rewriter.wrap(source_range, forward, backward)
end
process_requests(source_rewriter) click to toggle source
# File lib/transpec/dynamic_analyzer/rewriter.rb, line 65
def process_requests(source_rewriter)
  requests.each do |node, analysis_codes|
    inject_analysis_code(node, analysis_codes, source_rewriter)
  end
end