Class: Fast::Rewriter

Inherits:
Parser::TreeRewriter
  • Object
show all
Defined in:
lib/fast.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

ast = Fast.ast("a = 1")
buffer = Parser::Source::Buffer.new('replacement')
buffer.source = ast.loc.expression.source
rewriter = Rewriter.new
rewriter.buffer = buffer
rewriter.search ='(lvasgn _ ...)'
rewriter.replacement =  -> (node) { replace(node.location.name, 'variable_renamed') }
rewriter.replace_on(:lvasgn)
rewriter.rewrite(buffer, ast) # => "variable_renamed = 1"

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Rewriter

Returns a new instance of Rewriter.



257
258
259
260
# File 'lib/fast.rb', line 257

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

Instance Attribute Details

#bufferObject

Returns the value of attribute buffer.



256
257
258
# File 'lib/fast.rb', line 256

def buffer
  @buffer
end

#match_indexInteger (readonly)

Returns with occurrence index.

Returns:

  • (Integer)

    with occurrence index



255
256
257
# File 'lib/fast.rb', line 255

def match_index
  @match_index
end

#replacementObject

Returns the value of attribute replacement.



256
257
258
# File 'lib/fast.rb', line 256

def replacement
  @replacement
end

#searchObject

Returns the value of attribute search.



256
257
258
# File 'lib/fast.rb', line 256

def search
  @search
end

Instance Method Details

#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.



283
284
285
286
287
288
289
# File 'lib/fast.rb', line 283

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)


262
263
264
# File 'lib/fast.rb', line 262

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

#replace_on(*types) ⇒ Object

Generate methods for all affected types.

See Also:



268
269
270
271
272
273
274
275
276
277
278
# File 'lib/fast.rb', line 268

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