synvert-core 0.62.1 → 0.64.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.