Class: Synvert::Rewriter::Instance

Inherits:
Object
  • Object
show all
Defined in:
lib/synvert/rewriter/instance.rb

Overview

Instance is an execution unit, it finds specified ast nodes, checks if the nodes match some conditions, then add, replace or remove code.

One instance can contains one or many [Synvert::Rewriter::Scope] and [Synvert::Rewriter::Condition].

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_pattern, &block) ⇒ Synvert::Rewriter::Instance

Initialize an instance.

Parameters:

  • file_pattern (String)

    pattern to find files, e.g. spec/*/_spec.rb

  • block (Block)

    block code to find nodes, match conditions and rewrite code.



22
23
24
25
26
# File 'lib/synvert/rewriter/instance.rb', line 22

def initialize(file_pattern, &block)
  @actions = []
  @file_pattern = file_pattern
  @block = block
end

Instance Attribute Details

#current_fileObject

Returns current filename.

Returns:

  • current filename



15
# File 'lib/synvert/rewriter/instance.rb', line 15

attr_accessor :current_node, :current_source, :current_file

#current_nodeObject

Returns current parsing node.

Returns:

  • current parsing node



15
16
17
# File 'lib/synvert/rewriter/instance.rb', line 15

def current_node
  @current_node
end

#current_sourceObject

Returns current source code of file.

Returns:

  • current source code of file



15
# File 'lib/synvert/rewriter/instance.rb', line 15

attr_accessor :current_node, :current_source, :current_file

Instance Method Details

#append(code) ⇒ Object

Parse append dsl, it creates a [Synvert::Rewriter::AppendAction] to append the code to the bottom of current node body.

Parameters:

  • code (String)

    code need to be appended.



118
119
120
# File 'lib/synvert/rewriter/instance.rb', line 118

def append(code)
  @actions << Rewriter::AppendAction.new(self, code)
end

#if_exist_node(rules, &block) ⇒ Object

Parse if_exist_node dsl, it creates a [Synvert::Rewriter::IfExistCondition] to check if matching nodes exist in the child nodes, if so, then continue operating on each matching ast node.

Parameters:

  • rules (Hash)

    rules to check mathing ast nodes.

  • block (Block)

    block code to continue operating on the matching nodes.



91
92
93
# File 'lib/synvert/rewriter/instance.rb', line 91

def if_exist_node(rules, &block)
  Rewriter::IfExistCondition.new(self, rules, &block).process
end

#if_only_exist_node(rules, &block) ⇒ Object

Parse if_only_exist_node dsl, it creates a [Synvert::Rewriter::IfOnlyExistCondition] to check if current node has only one child node and the child node matches rules, if so, then continue operating on each matching ast node.

Parameters:

  • rules (Hash)

    rules to check mathing ast nodes.

  • block (Block)

    block code to continue operating on the matching nodes.



110
111
112
# File 'lib/synvert/rewriter/instance.rb', line 110

def if_only_exist_node(rules, &block)
  Rewriter::IfOnlyExistCondition.new(self, rules, &block).process
end

#insert(code) ⇒ Object

Parse insert dsl, it creates a [Synvert::Rewriter::InsertAction] to insert the code to the top of current node body.

Parameters:

  • code (String)

    code need to be inserted.



126
127
128
# File 'lib/synvert/rewriter/instance.rb', line 126

def insert(code)
  @actions << Rewriter::InsertAction.new(self, code)
end

#insert_after(node) ⇒ Object

Parse insert_after dsl, it creates a [Synvert::Rewriter::InsertAfterAction] to insert the code next to the current node.

Parameters:

  • code (String)

    code need to be inserted.



134
135
136
# File 'lib/synvert/rewriter/instance.rb', line 134

def insert_after(node)
  @actions << Rewriter::InsertAfterAction.new(self, node)
end

#nodeParser::AST::Node

Gets current node, it allows to get current node in block code.

Returns:



67
68
69
# File 'lib/synvert/rewriter/instance.rb', line 67

def node
  @current_node
end

#processObject

Process the instance. It finds all files, for each file, it executes the block code, gets all rewrite actions, and rewrite source code back to original file.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/synvert/rewriter/instance.rb', line 31

def process
  parser = Parser::CurrentRuby.new
  file_pattern = File.join(Configuration.instance.get(:path), @file_pattern)
  Dir.glob(file_pattern).each do |file_path|
    unless Configuration.instance.get(:skip_files).include? file_path
      begin
        source = File.read(file_path)
        buffer = Parser::Source::Buffer.new file_path
        buffer.source = source

        parser.reset
        ast = parser.parse buffer

        @current_file = file_path
        @current_source = source
        @current_node = ast
        instance_eval &@block
        @current_node = ast

        @actions.sort!
        check_conflict_actions
        @actions.reverse.each do |action|
          source[action.begin_pos...action.end_pos] = action.rewritten_code
          source = remove_code_or_whole_line(source, action.line)
        end
        @actions = []

        File.write file_path, source
      end while !@conflict_actions.empty?
    end
  end
end

#removeObject

Parse remove dsl, it creates a [Synvert::Rewriter::RemoveAction] to current node.



147
148
149
# File 'lib/synvert/rewriter/instance.rb', line 147

def remove
  @actions << Rewriter::RemoveAction.new(self)
end

#replace_with(code) ⇒ Object

Parse replace_with dsl, it creates a [Synvert::Rewriter::ReplaceWithAction] to replace current node with code.

Parameters:

  • code (String)

    code need to be replaced with.



142
143
144
# File 'lib/synvert/rewriter/instance.rb', line 142

def replace_with(code)
  @actions << Rewriter::ReplaceWithAction.new(self, code)
end

#unless_exist_node(rules, &block) ⇒ Object

Parse unless_exist_node dsl, it creates a [Synvert::Rewriter::UnlessExistCondition] to check if matching nodes doesn’t exist in the child nodes, if so, then continue operating on each matching ast node.

Parameters:

  • rules (Hash)

    rules to check mathing ast nodes.

  • block (Block)

    block code to continue operating on the matching nodes.



100
101
102
# File 'lib/synvert/rewriter/instance.rb', line 100

def unless_exist_node(rules, &block)
  Rewriter::UnlessExistCondition.new(self, rules, &block).process
end

#within_node(rules, &block) ⇒ Object Also known as: with_node

Parse within_node dsl, it creates a [Synvert::Rewriter::Scope] to find matching ast nodes, then continue operating on each matching ast node.

Parameters:

  • rules (Hash)

    rules to find mathing ast nodes.

  • block (Block)

    block code to continue operating on the matching nodes.



80
81
82
# File 'lib/synvert/rewriter/instance.rb', line 80

def within_node(rules, &block)
  Rewriter::Scope.new(self, rules, &block).process
end