synvert-core 0.62.1 → 0.64.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/Gemfile +0 -2
  4. data/README.md +73 -33
  5. data/lib/synvert/core/configuration.rb +12 -0
  6. data/lib/synvert/core/exceptions.rb +0 -4
  7. data/lib/synvert/core/node_ext.rb +206 -103
  8. data/lib/synvert/core/rewriter/action/append_action.rb +4 -3
  9. data/lib/synvert/core/rewriter/action/delete_action.rb +13 -6
  10. data/lib/synvert/core/rewriter/action/insert_action.rb +16 -7
  11. data/lib/synvert/core/rewriter/action/insert_after_action.rb +3 -2
  12. data/lib/synvert/core/rewriter/action/prepend_action.rb +3 -2
  13. data/lib/synvert/core/rewriter/action/remove_action.rb +16 -10
  14. data/lib/synvert/core/rewriter/action/replace_action.rb +13 -5
  15. data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +18 -11
  16. data/lib/synvert/core/rewriter/action/replace_with_action.rb +6 -5
  17. data/lib/synvert/core/rewriter/action/wrap_action.rb +13 -5
  18. data/lib/synvert/core/rewriter/action.rb +20 -9
  19. data/lib/synvert/core/rewriter/any_value.rb +1 -0
  20. data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +4 -0
  21. data/lib/synvert/core/rewriter/condition/if_only_exist_condition.rb +4 -0
  22. data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +4 -0
  23. data/lib/synvert/core/rewriter/condition.rb +11 -3
  24. data/lib/synvert/core/rewriter/gem_spec.rb +7 -4
  25. data/lib/synvert/core/rewriter/helper.rb +2 -2
  26. data/lib/synvert/core/rewriter/instance.rb +195 -94
  27. data/lib/synvert/core/rewriter/ruby_version.rb +4 -4
  28. data/lib/synvert/core/rewriter/scope/goto_scope.rb +5 -6
  29. data/lib/synvert/core/rewriter/scope/within_scope.rb +9 -4
  30. data/lib/synvert/core/rewriter/scope.rb +8 -0
  31. data/lib/synvert/core/rewriter/warning.rb +1 -1
  32. data/lib/synvert/core/rewriter.rb +90 -43
  33. data/lib/synvert/core/version.rb +1 -1
  34. data/lib/synvert/core.rb +0 -1
  35. data/spec/spec_helper.rb +0 -3
  36. data/spec/synvert/core/node_ext_spec.rb +28 -7
  37. data/spec/synvert/core/rewriter/action_spec.rb +0 -4
  38. data/spec/synvert/core/rewriter/gem_spec_spec.rb +11 -10
  39. data/spec/synvert/core/rewriter/instance_spec.rb +7 -17
  40. data/synvert-core-ruby.gemspec +2 -1
  41. metadata +21 -7
@@ -4,12 +4,12 @@ module Synvert::Core
4
4
  # Instance is an execution unit, it finds specified ast nodes,
5
5
  # checks if the nodes match some conditions, then add, replace or remove code.
6
6
  #
7
- # One instance can contains one or many [Synvert::Core::Rewriter::Scope] and [Synvert::Rewriter::Condition].
7
+ # One instance can contain one or many {Synvert::Core::Rewriter::Scope} and {Synvert::Rewriter::Condition}.
8
8
  class Rewriter::Instance
9
9
  include Rewriter::Helper
10
10
 
11
11
  class << self
12
- # Cached file source.
12
+ # Get file source.
13
13
  #
14
14
  # @param file_path [String] file path
15
15
  # @return [String] file source
@@ -23,7 +23,7 @@ module Synvert::Core
23
23
  end
24
24
  end
25
25
 
26
- # Cached file ast.
26
+ # Get file ast.
27
27
  #
28
28
  # @param file_path [String] file path
29
29
  # @return [String] ast node for file
@@ -51,7 +51,7 @@ module Synvert::Core
51
51
  @file_ast[file_path] = nil
52
52
  end
53
53
 
54
- # Reset cached file source and ast.
54
+ # Reset file source and ast.
55
55
  def reset
56
56
  @file_source = {}
57
57
  @file_ast = {}
@@ -69,12 +69,11 @@ module Synvert::Core
69
69
  self.class.file_source(current_file)
70
70
  end
71
71
 
72
- # Initialize an instance.
72
+ # Initialize an Instance.
73
73
  #
74
74
  # @param rewriter [Synvert::Core::Rewriter]
75
75
  # @param file_patterns [Array<String>] pattern list to find files, e.g. ['spec/**/*_spec.rb']
76
- # @param block [Block] block code to find nodes, match conditions and rewrite code.
77
- # @return [Synvert::Core::Rewriter::Instance]
76
+ # @yield block code to find nodes, match conditions and rewrite code.
78
77
  def initialize(rewriter, file_patterns, &block)
79
78
  @rewriter = rewriter
80
79
  @actions = []
@@ -84,44 +83,14 @@ module Synvert::Core
84
83
  end
85
84
 
86
85
  # Process the instance.
87
- # It finds all files, for each file, it executes the block code, gets all rewrite actions,
88
- # and rewrite source code back to original file.
86
+ # It finds specified files, for each file, it executes the block code, rewrites the original code,
87
+ # then write the code back to the original file.
89
88
  def process
90
89
  @file_patterns.each do |file_pattern|
91
90
  Dir.glob(File.join(Configuration.path, file_pattern)).each do |file_path|
92
- next if Configuration.skip_files.include? file_path
91
+ next if Configuration.skip_files.include?(file_path)
93
92
 
94
- begin
95
- puts file_path if Configuration.show_run_process
96
- conflict_actions = []
97
- source = +self.class.file_source(file_path)
98
- ast = self.class.file_ast(file_path)
99
-
100
- @current_file = file_path
101
-
102
- process_with_node ast do
103
- begin
104
- instance_eval(&@block)
105
- rescue NoMethodError
106
- puts @current_node.debug_info
107
- raise
108
- end
109
- end
110
-
111
- if @actions.length > 0
112
- @actions.sort_by! { |action| [action.begin_pos, action.end_pos] }
113
- conflict_actions = get_conflict_actions
114
- @actions.reverse_each do |action|
115
- source[action.begin_pos...action.end_pos] = action.rewritten_code
116
- end
117
- @actions = []
118
-
119
- update_file(file_path, source)
120
- end
121
- rescue Parser::SyntaxError
122
- puts "[Warn] file #{file_path} was not parsed correctly."
123
- # do nothing, iterate next file
124
- end while !conflict_actions.empty?
93
+ process_file(file_path)
125
94
  end
126
95
  end
127
96
  end
@@ -158,159 +127,291 @@ module Synvert::Core
158
127
  # DSL #
159
128
  #######
160
129
 
161
- # Parse within_node dsl, it creates a [Synvert::Core::Rewriter::WithinScope] to find recursive matching ast nodes,
130
+ # Parse +within_node+ dsl, it creates a {Synvert::Core::Rewriter::WithinScope} to recursively find matching ast nodes,
162
131
  # then continue operating on each matching ast node.
163
- #
132
+ # @example
133
+ # # matches User.find_by_login('test')
134
+ # with_node type: 'send', message: /^find_by_/ do
135
+ # end
164
136
  # @param rules [Hash] rules to find mathing ast nodes.
165
- # @param options [Hash] optional, set if stop_when_match or not.
166
- # @param block [Block] block code to continue operating on the matching nodes.
167
- def within_node(rules, options = nil, &block)
168
- options ||= { stop_when_match: false }
137
+ # @param options [Hash] optional
138
+ # @option stop_when_match [Boolean] set if stop when match, default is false
139
+ # @option direct [Boolean] set if find direct matching ast nodes, default is false
140
+ # @yield run on the matching nodes.
141
+ def within_node(rules, options = {}, &block)
142
+ options[:stop_when_match] ||= false
143
+ options[:direct] ||= false
169
144
  Rewriter::WithinScope.new(self, rules, options, &block).process
170
145
  end
171
146
 
172
147
  alias with_node within_node
173
148
 
174
- # Parse within_direct_node dsl, it creates a [Synvert::Core::Rewriter::WithinScope] to find direct matching ast nodes,
175
- # then continue operating on each matching ast node.
176
- #
177
- # @param rules [Hash] rules to find mathing ast nodes.
178
- # @param block [Block] block code to continue operating on the matching nodes.
179
- def within_direct_node(rules, &block)
180
- Rewriter::WithinScope.new(self, rules, { direct: true }, &block).process
181
- end
182
-
183
- alias with_direct_node within_direct_node
184
-
185
- # Parse goto_node dsl, it creates a [Synvert::Core::Rewriter::GotoScope] to go to a child node,
149
+ # Parse +goto_node+ dsl, it creates a {Synvert::Core::Rewriter::GotoScope} to go to a child node,
186
150
  # then continue operating on the child node.
187
- #
151
+ # @example
152
+ # # head status: 406
153
+ # with_node type: 'send', receiver: nil, message: 'head', arguments: { size: 1, first: { type: 'hash' } } do
154
+ # goto_node 'arguments.first' do
155
+ # end
156
+ # end
188
157
  # @param child_node_name [Symbol|String] the name of the child nodes.
189
158
  # @param block [Block] block code to continue operating on the matching nodes.
190
159
  def goto_node(child_node_name, &block)
191
160
  Rewriter::GotoScope.new(self, child_node_name, &block).process
192
161
  end
193
162
 
194
- # Parse if_exist_node dsl, it creates a [Synvert::Core::Rewriter::IfExistCondition] to check
163
+ # Parse +if_exist_node+ dsl, it creates a {Synvert::Core::Rewriter::IfExistCondition} to check
195
164
  # if matching nodes exist in the child nodes, if so, then continue operating on each matching ast node.
196
- #
165
+ # @example
166
+ # # Klass.any_instance.stub(:message)
167
+ # with_node type: 'send', message: 'stub', arguments: { first: { type: { not: 'hash' } } } do
168
+ # if_exist_node type: 'send', message: 'any_instance' do
169
+ # end
170
+ # end
197
171
  # @param rules [Hash] rules to check mathing ast nodes.
198
172
  # @param block [Block] block code to continue operating on the matching nodes.
199
173
  def if_exist_node(rules, &block)
200
174
  Rewriter::IfExistCondition.new(self, rules, &block).process
201
175
  end
202
176
 
203
- # Parse unless_exist_node dsl, it creates a [Synvert::Core::Rewriter::UnlessExistCondition] to check
177
+ # Parse +unless_exist_node+ dsl, it creates a {Synvert::Core::Rewriter::UnlessExistCondition} to check
204
178
  # if matching nodes doesn't exist in the child nodes, if so, then continue operating on each matching ast node.
205
- #
179
+ # @example
180
+ # # obj.stub(:message)
181
+ # with_node type: 'send', message: 'stub', arguments: { first: { type: { not: 'hash' } } } do
182
+ # unless_exist_node type: 'send', message: 'any_instance' do
183
+ # end
184
+ # end
206
185
  # @param rules [Hash] rules to check mathing ast nodes.
207
186
  # @param block [Block] block code to continue operating on the matching nodes.
208
187
  def unless_exist_node(rules, &block)
209
188
  Rewriter::UnlessExistCondition.new(self, rules, &block).process
210
189
  end
211
190
 
212
- # Parse if_only_exist_node dsl, it creates a [Synvert::Core::Rewriter::IfOnlyExistCondition] to check
191
+ # Parse +if_only_exist_node+ dsl, it creates a {Synvert::Core::Rewriter::IfOnlyExistCondition} to check
213
192
  # if current node has only one child node and the child node matches rules,
214
193
  # if so, then continue operating on each matching ast node.
215
- #
194
+ # @example
195
+ # # it { should matcher }
196
+ # with_node type: 'block', caller: { message: 'it' } do
197
+ # if_only_exist_node type: 'send', receiver: nil, message: 'should' do
198
+ # end
199
+ # end
216
200
  # @param rules [Hash] rules to check mathing ast nodes.
217
201
  # @param block [Block] block code to continue operating on the matching nodes.
218
202
  def if_only_exist_node(rules, &block)
219
203
  Rewriter::IfOnlyExistCondition.new(self, rules, &block).process
220
204
  end
221
205
 
222
- # Parse append dsl, it creates a [Synvert::Core::Rewriter::AppendAction] to
206
+ # Parse +append+ dsl, it creates a {Synvert::Core::Rewriter::AppendAction} to
223
207
  # append the code to the bottom of current node body.
224
- #
208
+ # @example
209
+ # # def teardown
210
+ # # clean_something
211
+ # # end
212
+ # # =>
213
+ # # def teardown
214
+ # # clean_something
215
+ # # super
216
+ # # end
217
+ # with_node type: 'def', name: 'steardown' do
218
+ # append 'super'
219
+ # end
225
220
  # @param code [String] code need to be appended.
226
221
  def append(code)
227
222
  @actions << Rewriter::AppendAction.new(self, code).process
228
223
  end
229
224
 
230
- # Parse prepend dsl, it creates a [Synvert::Core::Rewriter::PrependAction] to
225
+ # Parse +prepend+ dsl, it creates a {Synvert::Core::Rewriter::PrependAction} to
231
226
  # prepend the code to the top of current node body.
232
- #
227
+ # @example
228
+ # # def setup
229
+ # # do_something
230
+ # # end
231
+ # # =>
232
+ # # def setup
233
+ # # super
234
+ # # do_something
235
+ # # end
236
+ # with_node type: 'def', name: 'setup' do
237
+ # prepend 'super'
238
+ # end
233
239
  # @param code [String] code need to be prepended.
234
240
  def prepend(code)
235
241
  @actions << Rewriter::PrependAction.new(self, code).process
236
242
  end
237
243
 
238
- # Parse insert dsl, it creates a [Synvert::Core::Rewriter::InsertAction] to
239
- # insert the code to the top of current node body.
240
- #
244
+ # Parse +insert+ dsl, it creates a {Synvert::Core::Rewriter::InsertAction} to insert code.
245
+ # @example
246
+ # # open('http://test.com')
247
+ # # =>
248
+ # # URI.open('http://test.com')
249
+ # with_node type: 'send', receiver: nil, message: 'open' do
250
+ # insert 'URI.', at: 'beginning'
251
+ # end
241
252
  # @param code [String] code need to be inserted.
242
- # @param at [String] insert position, beginning or end, end is the default.
253
+ # @param at [String] insert position, beginning or end
243
254
  # @param to [String] where to insert, if it is nil, will insert to current node.
244
255
  def insert(code, at: 'end', to: nil)
245
256
  @actions << Rewriter::InsertAction.new(self, code, at: at, to: to).process
246
257
  end
247
258
 
248
- # Parse insert_after dsl, it creates a [Synvert::Core::Rewriter::InsertAfterAction] to
259
+ # Parse +insert_after+ dsl, it creates a {Synvert::Core::Rewriter::InsertAfterAction} to
249
260
  # insert the code next to the current node.
250
- #
261
+ # @example
262
+ # # Synvert::Application.config.secret_token = "0447aa931d42918bfb934750bb78257088fb671186b5d1b6f9fddf126fc8a14d34f1d045cefab3900751c3da121a8dd929aec9bafe975f1cabb48232b4002e4e"
263
+ # # =>
264
+ # # Synvert::Application.config.secret_token = "0447aa931d42918bfb934750bb78257088fb671186b5d1b6f9fddf126fc8a14d34f1d045cefab3900751c3da121a8dd929aec9bafe975f1cabb48232b4002e4e"
265
+ # # Synvert::Application.config.secret_key_base = "bf4f3f46924ecd9adcb6515681c78144545bba454420973a274d7021ff946b8ef043a95ca1a15a9d1b75f9fbdf85d1a3afaf22f4e3c2f3f78e24a0a188b581df"
266
+ # with_node type: 'send', message: 'secret_token=' do
267
+ # insert_after "{{receiver}}.secret_key_base = \"#{SecureRandom.hex(64)}\""
268
+ # end
251
269
  # @param code [String] code need to be inserted.
252
- def insert_after(node)
253
- @actions << Rewriter::InsertAfterAction.new(self, node).process
270
+ def insert_after(code)
271
+ @actions << Rewriter::InsertAfterAction.new(self, code).process
254
272
  end
255
273
 
256
- # Parse replace_with dsl, it creates a [Synvert::Core::Rewriter::ReplaceWithAction] to
257
- # replace current node with code.
258
- #
274
+ # Parse +replace_with+ dsl, it creates a {Synvert::Core::Rewriter::ReplaceWithAction} to
275
+ # replace the whole code of current node.
276
+ # @example
277
+ # # obj.stub(:foo => 1, :bar => 2)
278
+ # # =>
279
+ # # allow(obj).to receive_messages(:foo => 1, :bar => 2)
280
+ # with_node type: 'send', message: 'stub', arguments: { first: { type: 'hash' } } do
281
+ # replace_with 'allow({{receiver}}).to receive_messages({{arguments}})'
282
+ # end
259
283
  # @param code [String] code need to be replaced with.
260
284
  def replace_with(code)
261
285
  @actions << Rewriter::ReplaceWithAction.new(self, code).process
262
286
  end
263
287
 
264
- # Parse replace with dsl, it creates a [Synvert::Core::Rewriter::ReplaceAction] to
265
- # replace child nodes with code.
266
- #
288
+ # Parse +replace+ dsl, it creates a {Synvert::Core::Rewriter::ReplaceAction} to
289
+ # replace the code of specified child nodes.
290
+ # @example
291
+ # # assert(object.empty?)
292
+ # # =>
293
+ # # assert_empty(object)
294
+ # with_node type: 'send', receiver: nil, message: 'assert', arguments: { size: 1, first: { type: 'send', message: 'empty?', arguments: { size: 0 } } } do
295
+ # replace :message, with: 'assert_empty'
296
+ # replace :arguments, with: '{{arguments.first.receiver}}'
297
+ # end
267
298
  # @param selectors [Array<Symbol>] selector names of child node.
268
299
  # @param with [String] code need to be replaced with.
269
300
  def replace(*selectors, with:)
270
301
  @actions << Rewriter::ReplaceAction.new(self, *selectors, with: with).process
271
302
  end
272
303
 
273
- # Parse replace_erb_stmt_with_expr dsl, it creates a [Synvert::Core::Rewriter::ReplaceErbStmtWithExprAction] to
304
+ # Parse +replace_erb_stmt_with_expr+ dsl, it creates a {Synvert::Core::Rewriter::ReplaceErbStmtWithExprAction} to
274
305
  # replace erb stmt code to expr code.
306
+ # @example
307
+ # # <% form_for post do |f| %>
308
+ # # <% end %>
309
+ # # =>
310
+ # # <%= form_for post do |f| %>
311
+ # # <% end %>
312
+ # with_node type: 'block', caller: { type: 'send', receiver: nil, message: 'form_for' } do
313
+ # replace_erb_stmt_with_expr
314
+ # end
275
315
  def replace_erb_stmt_with_expr
276
316
  @actions << Rewriter::ReplaceErbStmtWithExprAction.new(self).process
277
317
  end
278
318
 
279
- # Parse remove dsl, it creates a [Synvert::Core::Rewriter::RemoveAction] to remove current node.
319
+ # Parse +remove+ dsl, it creates a {Synvert::Core::Rewriter::RemoveAction} to remove current node.
320
+ # @example
321
+ # with_node type: 'send', message: { in: %w[puts p] } do
322
+ # remove
323
+ # end
280
324
  def remove
281
325
  @actions << Rewriter::RemoveAction.new(self).process
282
326
  end
283
327
 
284
- # Parse delete dsl, it creates a [Synvert::Core::Rewriter::DeleteAction] to delete child nodes.
285
- #
328
+ # Parse +delete+ dsl, it creates a {Synvert::Core::Rewriter::DeleteAction} to delete child nodes.
329
+ # @example
330
+ # # FactoryBot.create(...)
331
+ # # =>
332
+ # # create(...)
333
+ # with_node type: 'send', receiver: 'FactoryBot', message: 'create' do
334
+ # delete :receiver, :dot
335
+ # end
286
336
  # @param selectors [Array<Symbol>] selector names of child node.
287
337
  def delete(*selectors)
288
338
  @actions << Rewriter::DeleteAction.new(self, *selectors).process
289
339
  end
290
340
 
291
- # Parse wrap with dsl, it creates a [Synvert::Core::Rewriter::WrapAction] to
341
+ # Parse +wrap+ dsl, it creates a {Synvert::Core::Rewriter::WrapAction} to
292
342
  # wrap current node with code.
293
- #
343
+ # @example
344
+ # # class Foobar
345
+ # # end
346
+ # # =>
347
+ # # module Synvert
348
+ # # class Foobar
349
+ # # end
350
+ # # end
351
+ # within_node type: 'class' do
352
+ # wrap with: 'module Synvert'
353
+ # end
294
354
  # @param with [String] code need to be wrapped with.
295
- # @param indent [Integer] number of whitespaces.
355
+ # @param indent [Integer, nil] number of whitespaces.
296
356
  def wrap(with:, indent: nil)
297
357
  @actions << Rewriter::WrapAction.new(self, with: with, indent: indent).process
298
358
  end
299
359
 
300
- # Parse warn dsl, it creates a [Synvert::Core::Rewriter::Warning] to save warning message.
301
- #
360
+ # Parse +warn+ dsl, it creates a {Synvert::Core::Rewriter::Warning} to save warning message.
361
+ # @example
362
+ # within_files 'vendor/plugins' do
363
+ # warn 'Rails::Plugin is deprecated and will be removed in Rails 4.0. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies.'
364
+ # end
302
365
  # @param message [String] warning message.
303
366
  def warn(message)
304
367
  @rewriter.add_warning Rewriter::Warning.new(self, message)
305
368
  end
306
369
 
307
- # Any value but nil.
370
+ # Match any value but nil.
371
+ # @example
372
+ # type: 'hash', nothing_value: 'true', status_value: any_value
373
+ # @return [Synvert::Core::Rewriter::AnyValue]
308
374
  def any_value
309
375
  Rewriter::AnyValue.new
310
376
  end
311
377
 
312
378
  private
313
379
 
380
+ # Process one file.
381
+ #
382
+ # @param file_path [String]
383
+ def process_file(file_path)
384
+ begin
385
+ puts file_path if Configuration.show_run_process
386
+ conflict_actions = []
387
+ source = +self.class.file_source(file_path)
388
+ ast = self.class.file_ast(file_path)
389
+
390
+ @current_file = file_path
391
+
392
+ process_with_node(ast) do
393
+ instance_eval(&@block)
394
+ rescue NoMethodError
395
+ puts @current_node.debug_info
396
+ raise
397
+ end
398
+
399
+ if @actions.length > 0
400
+ @actions.sort_by! { |action| [action.begin_pos, action.end_pos] }
401
+ conflict_actions = get_conflict_actions
402
+ @actions.reverse_each do |action|
403
+ source[action.begin_pos...action.end_pos] = action.rewritten_code
404
+ end
405
+ @actions = []
406
+
407
+ update_file(file_path, source)
408
+ end
409
+ rescue Parser::SyntaxError
410
+ puts "[Warn] file #{file_path} was not parsed correctly."
411
+ # do nothing, iterate next file
412
+ end while !conflict_actions.empty?
413
+ end
414
+
314
415
  # It changes source code from bottom to top, and it can change source code twice at the same time,
315
416
  # So if there is an overlap between two actions, it removes the conflict actions and operate them in the next loop.
316
417
  def get_conflict_actions
@@ -17,13 +17,13 @@ module Synvert::Core
17
17
  # @return [Boolean] true if matches, otherwise false.
18
18
  def match?
19
19
  if File.exist?(File.join(Configuration.path, '.ruby-version'))
20
- versionFile = '.ruby-version'
20
+ version_file = '.ruby-version'
21
21
  elsif File.exist?(File.join(Configuration.path, '.rvmrc'))
22
- versionFile = '.rvmrc'
22
+ version_file = '.rvmrc'
23
23
  end
24
- return true unless versionFile
24
+ return true unless version_file
25
25
 
26
- version = File.read(File.join(Configuration.path, versionFile))
26
+ version = File.read(File.join(Configuration.path, version_file))
27
27
  Gem::Version.new(version) >= Gem::Version.new(@version)
28
28
  end
29
29
  end
@@ -3,18 +3,17 @@
3
3
  module Synvert::Core
4
4
  # Go to and change its scope to a child node.
5
5
  class Rewriter::GotoScope < Rewriter::Scope
6
- # Initialize a scope
6
+ # Initialize a GotoScope.
7
7
  #
8
8
  # @param instance [Synvert::Core::Rewriter::Instance]
9
- # @param child_node_name [Symbol|string]
10
- # @param block [Block]
9
+ # @param child_node_name [Symbol|String] name of child node
10
+ # @yield run on the child node
11
11
  def initialize(instance, child_node_name, &block)
12
- @instance = instance
12
+ super(instance, &block)
13
13
  @child_node_name = child_node_name
14
- @block = block
15
14
  end
16
15
 
17
- # Go to a child now, then run the block code with the the child node.
16
+ # Go to a child now, then run the block code on the the child node.
18
17
  def process
19
18
  current_node = @instance.current_node
20
19
  return unless current_node
@@ -3,17 +3,16 @@
3
3
  module Synvert::Core
4
4
  # WithinScope finds out nodes which match rules, then changes its scope to matching node.
5
5
  class Rewriter::WithinScope < Rewriter::Scope
6
- # Initialize a scope
6
+ # Initialize a WithinScope.
7
7
  #
8
8
  # @param instance [Synvert::Core::Rewriter::Instance]
9
9
  # @param rules [Hash]
10
10
  # @param options [Hash]
11
- # @param block [Block]
11
+ # @yield run on all matching nodes
12
12
  def initialize(instance, rules, options = {}, &block)
13
- @instance = instance
13
+ super(instance, &block)
14
14
  @rules = rules
15
15
  @options = options
16
- @block = block
17
16
  end
18
17
 
19
18
  # Find out the matching nodes.
@@ -43,6 +42,8 @@ module Synvert::Core
43
42
  private
44
43
 
45
44
  # Find the matching nodes only in current or direct children.
45
+ #
46
+ # @param current_node [Parser::AST::Node]
46
47
  def find_direct_matching_nodes(current_node)
47
48
  matching_nodes = []
48
49
  if current_node.is_a?(Parser::AST::Node)
@@ -62,6 +63,8 @@ module Synvert::Core
62
63
  end
63
64
 
64
65
  # Find matching nodes in all recursive children.
66
+ #
67
+ # @param current_node [Parser::AST::Node]
65
68
  def find_recursive_matching_nodes(current_node)
66
69
  matching_nodes = []
67
70
  if current_node.is_a?(Parser::AST::Node)
@@ -81,6 +84,8 @@ module Synvert::Core
81
84
  end
82
85
 
83
86
  # Find matching nodes in recursive children but do not continue on matching nodes.
87
+ #
88
+ # @param current_node [Parser::AST::Node]
84
89
  def find_matching_nodes(current_node)
85
90
  matching_nodes = []
86
91
  if current_node.is_a?(Parser::AST::Node)
@@ -3,5 +3,13 @@
3
3
  module Synvert::Core
4
4
  # Scope finds out nodes which match rules.
5
5
  class Rewriter::Scope
6
+ # Initialize a Scope
7
+ #
8
+ # @param instance [Synvert::Core::Rewriter::Instance]
9
+ # @yield run on a scope
10
+ def initialize(instance, &block)
11
+ @instance = instance
12
+ @block = block
13
+ end
6
14
  end
7
15
  end
@@ -3,7 +3,7 @@
3
3
  module Synvert::Core
4
4
  # Warning is used to save warning message.
5
5
  class Rewriter::Warning
6
- # Initialize a warning.
6
+ # Initialize a Warning.
7
7
  #
8
8
  # @param instance [Synvert::Core::Rewriter::Instance]
9
9
  # @param message [String] warning message.