Class: Synvert::Core::Rewriter::Instance
- Inherits:
-
Object
- Object
- Synvert::Core::Rewriter::Instance
- 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].
Instance Attribute Summary collapse
-
#current_file ⇒ Object
Current filename.
-
#current_node ⇒ Object
Current parsing node.
Class Method Summary collapse
-
.file_ast(file_path) ⇒ String
Cached file ast.
-
.file_source(file_path) ⇒ String
Cached file source.
-
.reset ⇒ Object
Reset cached file source and ast.
-
.write_file(file_path, source) ⇒ Object
Write source to file and remove cached file source and ast.
Instance Method Summary collapse
-
#append(code) ⇒ Object
Parse append dsl, it creates a [Synvert::Core::Rewriter::AppendAction] to append the code to the bottom of current node body.
-
#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.
-
#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.
-
#initialize(rewriter, file_pattern, &block) ⇒ Synvert::Core::Rewriter::Instance
constructor
Initialize an instance.
-
#insert(code) ⇒ Object
Parse insert dsl, it creates a [Synvert::Core::Rewriter::InsertAction] to insert the code to the top of current node body.
-
#insert_after(node) ⇒ Object
Parse insert_after dsl, it creates a [Synvert::Core::Rewriter::InsertAfterAction] to insert the code next to the current node.
-
#node ⇒ Parser::AST::Node
Gets current node, it allows to get current node in block code.
-
#process ⇒ Object
Process the instance.
-
#remove ⇒ Object
Parse remove dsl, it creates a [Synvert::Core::Rewriter::RemoveAction] to current node.
-
#replace_erb_stmt_with_expr ⇒ Object
Parse replace_erb_stmt_with_expr dsl, it creates a [Synvert::Core::Rewriter::ReplaceErbStmtWithExprAction] to replace erb stmt code to expr code.
-
#replace_with(code) ⇒ Object
Parse replace_with dsl, it creates a [Synvert::Core::Rewriter::ReplaceWithAction] to replace current node with code.
-
#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.
-
#warn(message) ⇒ Object
Parse warn dsl, it creates a [Synvert::Core::Rewriter::Warning] to save warning message.
-
#within_node(rules, &block) ⇒ Object
(also: #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.
Methods included from Helper
#add_receiver_if_necessary, #process_with_node, #process_with_other_node, #strip_brackets
Constructor Details
#initialize(rewriter, file_pattern, &block) ⇒ Synvert::Core::Rewriter::Instance
Initialize an instance.
73 74 75 76 77 78 79 |
# File 'lib/synvert/core/rewriter/instance.rb', line 73 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 |
Instance Attribute Details
#current_file ⇒ Object
65 |
# File 'lib/synvert/core/rewriter/instance.rb', line 65 attr_accessor :current_node, :current_file |
#current_node ⇒ Object
65 66 67 |
# File 'lib/synvert/core/rewriter/instance.rb', line 65 def current_node @current_node end |
Class Method Details
.file_ast(file_path) ⇒ String
Cached file ast.
30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/synvert/core/rewriter/instance.rb', line 30 def file_ast(file_path) @file_ast ||= {} @file_ast[file_path] ||= begin buffer = Parser::Source::Buffer.new file_path buffer.source = file_source(file_path) parser = Parser::CurrentRuby.new parser.reset parser.parse buffer end end |
.file_source(file_path) ⇒ String
Cached file source.
16 17 18 19 20 21 22 23 24 |
# File 'lib/synvert/core/rewriter/instance.rb', line 16 def file_source(file_path) @file_source ||= {} @file_source[file_path] ||= begin source = File.read(file_path) source = Engine::ERB.encode(source) if file_path =~ /\.erb$/ source end end |
.reset ⇒ Object
Reset cached file source and ast.
55 56 57 58 |
# File 'lib/synvert/core/rewriter/instance.rb', line 55 def reset @file_source = {} @file_ast = {} end |
.write_file(file_path, source) ⇒ Object
Write source to file and remove cached file source and ast.
47 48 49 50 51 52 |
# File 'lib/synvert/core/rewriter/instance.rb', line 47 def write_file(file_path, source) source = Engine::ERB.decode(source) if file_path =~ /\.erb/ File.write file_path, source @file_source[file_path] = nil @file_ast[file_path] = nil end |
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.
169 170 171 |
# File 'lib/synvert/core/rewriter/instance.rb', line 169 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.
142 143 144 |
# File 'lib/synvert/core/rewriter/instance.rb', line 142 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.
161 162 163 |
# File 'lib/synvert/core/rewriter/instance.rb', line 161 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.
177 178 179 |
# File 'lib/synvert/core/rewriter/instance.rb', line 177 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.
185 186 187 |
# File 'lib/synvert/core/rewriter/instance.rb', line 185 def insert_after(node) @actions << Rewriter::InsertAfterAction.new(self, node) end |
#node ⇒ Parser::AST::Node
Gets current node, it allows to get current node in block code.
118 119 120 |
# File 'lib/synvert/core/rewriter/instance.rb', line 118 def node @current_node end |
#process ⇒ Object
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.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/synvert/core/rewriter/instance.rb', line 84 def process 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 conflict_actions = [] source = self.class.file_source(file_path) ast = self.class.file_ast(file_path) @current_file = file_path self.process_with_node ast do instance_eval &@block end if @actions.length > 0 @actions.sort! conflict_actions = get_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 = [] self.class.write_file(file_path, source) end end while !conflict_actions.empty? end end end |
#remove ⇒ Object
Parse remove dsl, it creates a [Synvert::Core::Rewriter::RemoveAction] to current node.
204 205 206 |
# File 'lib/synvert/core/rewriter/instance.rb', line 204 def remove @actions << Rewriter::RemoveAction.new(self) end |
#replace_erb_stmt_with_expr ⇒ Object
Parse replace_erb_stmt_with_expr dsl, it creates a [Synvert::Core::Rewriter::ReplaceErbStmtWithExprAction] to replace erb stmt code to expr code.
199 200 201 |
# File 'lib/synvert/core/rewriter/instance.rb', line 199 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.
193 194 195 |
# File 'lib/synvert/core/rewriter/instance.rb', line 193 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.
151 152 153 |
# File 'lib/synvert/core/rewriter/instance.rb', line 151 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.
211 212 213 |
# File 'lib/synvert/core/rewriter/instance.rb', line 211 def warn() @rewriter.add_warning Rewriter::Warning.new(self, ) 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.
131 132 133 |
# File 'lib/synvert/core/rewriter/instance.rb', line 131 def within_node(rules, &block) Rewriter::Scope.new(self, rules, &block).process end |