Class: Fast::Rewriter

Inherits:
Parser::TreeRewriter
  • Object
show all
Defined in:
lib/fast/rewriter.rb

Overview

Note:

the standalone class needs to combines #replace_on to properly generate the ‘on_<node-type>` methods depending on the expression being used.

Rewriter encapsulates #match_index to allow ExperimentFile#partial_replace in a ExperimentFile.

Examples:

Simple Rewriter

rewriter = Rewriter.new buffer
rewriter.ast = Fast.ast("a = 1")
rewriter.search ='(lvasgn _ ...)'
rewriter.replacement =  -> (node) { replace(node.location.name, 'variable_renamed') }
rewriter.rewrite! # => "variable_renamed = 1"

See Also:

Direct Known Subclasses

SQL::Rewriter

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*_args) ⇒ Rewriter

Returns a new instance of Rewriter.



61
62
63
64
# File 'lib/fast/rewriter.rb', line 61

def initialize(*_args)
  super()
  @match_index = 0
end

Instance Attribute Details

#astObject

Returns the value of attribute ast.



60
61
62
# File 'lib/fast/rewriter.rb', line 60

def ast
  @ast
end

#match_indexInteger (readonly)

Returns with occurrence index.

Returns:

  • (Integer)

    with occurrence index



59
60
61
# File 'lib/fast/rewriter.rb', line 59

def match_index
  @match_index
end

#replacementObject

Returns the value of attribute replacement.



60
61
62
# File 'lib/fast/rewriter.rb', line 60

def replacement
  @replacement
end

#searchObject

Returns the value of attribute search.



60
61
62
# File 'lib/fast/rewriter.rb', line 60

def search
  @search
end

#sourceObject

Returns the value of attribute source.



60
61
62
# File 'lib/fast/rewriter.rb', line 60

def source
  @source
end

Instance Method Details

#bufferObject



71
72
73
74
75
# File 'lib/fast/rewriter.rb', line 71

def buffer
  buffer = Parser::Source::Buffer.new('replacement')
  buffer.source = source || ast.loc.expression.source
  buffer
end

#execute_replacement(node, captures) ⇒ Object

Execute #replacement block

Parameters:

  • node (Astrolabe::Node)

    that will be yield in the replacement block

  • captures (Array<Object>, nil)

    are yield if #replacement take second argument.



103
104
105
106
107
108
109
# File 'lib/fast/rewriter.rb', line 103

def execute_replacement(node, captures)
  if replacement.parameters.length == 1
    instance_exec node, &replacement
  else
    instance_exec node, captures, &replacement
  end
end

#match?(node) ⇒ Boolean

Returns:

  • (Boolean)


82
83
84
# File 'lib/fast/rewriter.rb', line 82

def match?(node)
  Fast.match?(search, node)
end

#replace_on(*types) ⇒ Object

Generate methods for all affected types.

See Also:



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/fast/rewriter.rb', line 88

def replace_on(*types)
  types.map do |type|
    self.class.send :define_method, "on_#{type}" do |node|
      if captures = match?(node) # rubocop:disable Lint/AssignmentInCondition
        @match_index += 1
        execute_replacement(node, captures)
      end
      super(node)
    end
  end
end

#rewrite!Object



66
67
68
69
# File 'lib/fast/rewriter.rb', line 66

def rewrite!
  replace_on(*types)
  rewrite(buffer, ast)
end

#typesArray<Symbol>

Returns with all types that matches.

Returns:

  • (Array<Symbol>)

    with all types that matches



78
79
80
# File 'lib/fast/rewriter.rb', line 78

def types
  Fast.search(search, ast).grep(Parser::AST::Node).map(&:type).uniq
end