Class: Synvert::Core::Rewriter::Instance

Inherits:
Object
  • Object
show all
Includes:
Helper
Defined in:
lib/synvert/core/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::Core::Rewriter::Scope] and [Synvert::Rewriter::Condition].

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helper

#add_receiver_if_necessary, #strip_brackets

Constructor Details

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

Initialize an instance.

Parameters:

  • rewriter (Synvert::Core::Rewriter)
  • file_pattern (String)

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

  • block (Block)

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



29
30
31
32
33
34
35
# File 'lib/synvert/core/rewriter/instance.rb', line 29

def initialize(rewriter, file_pattern, &block)
  @rewriter = rewriter
  @actions = []
  @file_pattern = file_pattern
  @block = block
  rewriter.helpers.each { |helper| self.singleton_class.send(:define_method, helper[:name], &helper[:block]) }
end

Class Attribute Details

.currentObject

Returns the value of attribute current.



12
13
14
# File 'lib/synvert/core/rewriter/instance.rb', line 12

def current
  @current
end

Instance Attribute Details

#current_fileObject

Returns current filename.

Returns:

  • current filename



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

attr_accessor :current_node, :current_source, :current_file

#current_nodeObject

Returns current parsing node.

Returns:

  • current parsing node



21
22
23
# File 'lib/synvert/core/rewriter/instance.rb', line 21

def current_node
  @current_node
end

#current_sourceObject

Returns current source code of file.

Returns:

  • current source code of file



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

attr_accessor :current_node, :current_source, :current_file

Instance Method Details

#append(code) ⇒ Object

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

Parameters:

  • code (String)

    code need to be appended.



131
132
133
# File 'lib/synvert/core/rewriter/instance.rb', line 131

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::Core::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.



104
105
106
# File 'lib/synvert/core/rewriter/instance.rb', line 104

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::Core::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.



123
124
125
# File 'lib/synvert/core/rewriter/instance.rb', line 123

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::Core::Rewriter::InsertAction] to insert the code to the top of current node body.

Parameters:

  • code (String)

    code need to be inserted.



139
140
141
# File 'lib/synvert/core/rewriter/instance.rb', line 139

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

#insert_after(node) ⇒ Object

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

Parameters:

  • code (String)

    code need to be inserted.



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

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:



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

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.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/synvert/core/rewriter/instance.rb', line 40

def process
  self.class.current = self

  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)
        source = Engine::ERB.encode(source) if file_path =~ /\.erb$/
        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 = []

        source = Engine::ERB.decode(source) if file_path =~ /\.erb/
        File.write file_path, source
      end while !@conflict_actions.empty?
    end
  end
end

#removeObject

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



166
167
168
# File 'lib/synvert/core/rewriter/instance.rb', line 166

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

#replace_erb_stmt_with_exprObject

Parse replace_erb_stmt_with_expr dsl, it creates a [Synvert::Core::Rewriter::ReplaceErbStmtWithExprAction] to replace erb stmt code to expr code.



161
162
163
# File 'lib/synvert/core/rewriter/instance.rb', line 161

def replace_erb_stmt_with_expr
  @actions << Rewriter::ReplaceErbStmtWithExprAction.new(self)
end

#replace_with(code) ⇒ Object

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

Parameters:

  • code (String)

    code need to be replaced with.



155
156
157
# File 'lib/synvert/core/rewriter/instance.rb', line 155

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::Core::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.



113
114
115
# File 'lib/synvert/core/rewriter/instance.rb', line 113

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

#warn(message) ⇒ Object

Parse warn dsl, it creates a [Synvert::Core::Rewriter::Warning] to save warning message.

Parameters:

  • message (String)

    warning message.



173
174
175
# File 'lib/synvert/core/rewriter/instance.rb', line 173

def warn(message)
  @rewriter.add_warning Rewriter::Warning.new(self, message)
end

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

Parse within_node dsl, it creates a [Synvert::Core::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.



93
94
95
# File 'lib/synvert/core/rewriter/instance.rb', line 93

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