Class: Fast::Rewriter

Inherits:
Object
  • 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.



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

def initialize(*_args)
  @match_index = 0
end

Instance Attribute Details

#astObject

Returns the value of attribute ast.



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

def ast
  @ast
end

#match_indexInteger (readonly)

Returns with occurrence index.

Returns:

  • (Integer)

    with occurrence index



64
65
66
# File 'lib/fast/rewriter.rb', line 64

def match_index
  @match_index
end

#replacementObject

Returns the value of attribute replacement.



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

def replacement
  @replacement
end

#searchObject

Returns the value of attribute search.



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

def search
  @search
end

#sourceObject

Returns the value of attribute source.



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

def source
  @source
end

Instance Method Details

#bufferObject



75
76
77
# File 'lib/fast/rewriter.rb', line 75

def buffer
  Fast::Source.buffer('replacement', source: source || ast.loc.expression.source)
end

#execute_replacement(node, captures) ⇒ Object

Execute #replacement block

Parameters:

  • node (Fast::Node)

    that will be yield in the replacement block

  • captures (Array<Object>, nil)

    are yield if #replacement take second argument.



131
132
133
134
135
136
137
# File 'lib/fast/rewriter.rb', line 131

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

#insert_after(range, content) ⇒ Object



120
121
122
# File 'lib/fast/rewriter.rb', line 120

def insert_after(range, content)
  @source_rewriter.insert_after(range, content)
end

#insert_before(range, content) ⇒ Object



116
117
118
# File 'lib/fast/rewriter.rb', line 116

def insert_before(range, content)
  @source_rewriter.insert_before(range, content)
end

#match?(node) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
# File 'lib/fast/rewriter.rb', line 90

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

#remove(range) ⇒ Object



108
109
110
# File 'lib/fast/rewriter.rb', line 108

def remove(range)
  @source_rewriter.remove(range)
end

#replace(range, content) ⇒ Object



124
125
126
# File 'lib/fast/rewriter.rb', line 124

def replace(range, content)
  @source_rewriter.replace(range, content)
end

#replace_on(*types) ⇒ Object

Generate methods for all affected types.

See Also:



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/fast/rewriter.rb', line 96

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
      traverse_children(node)
    end
  end
end

#rewrite(source_buffer, root) ⇒ Object



79
80
81
82
83
# File 'lib/fast/rewriter.rb', line 79

def rewrite(source_buffer, root)
  @source_rewriter = Fast::SourceRewriter.new(source_buffer)
  traverse(root)
  @source_rewriter.process
end

#rewrite!Object



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

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



86
87
88
# File 'lib/fast/rewriter.rb', line 86

def types
  Fast.search(search, ast).select { |node| Fast.ast_node?(node) }.map(&:type).uniq
end

#wrap(range, before, after) ⇒ Object



112
113
114
# File 'lib/fast/rewriter.rb', line 112

def wrap(range, before, after)
  @source_rewriter.wrap(range, before, after)
end