synvert-core 1.4.0 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -4
  3. data/CHANGELOG.md +6 -0
  4. data/Gemfile +0 -3
  5. data/Guardfile +0 -9
  6. data/README.md +30 -12
  7. data/Rakefile +1 -15
  8. data/lib/synvert/core/engine/erb.rb +1 -1
  9. data/lib/synvert/core/engine.rb +1 -1
  10. data/lib/synvert/core/node_ext.rb +0 -466
  11. data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +20 -17
  12. data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +1 -1
  13. data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +1 -1
  14. data/lib/synvert/core/rewriter/instance.rb +83 -133
  15. data/lib/synvert/core/rewriter/scope/query_scope.rb +2 -2
  16. data/lib/synvert/core/rewriter/scope/within_scope.rb +4 -4
  17. data/lib/synvert/core/rewriter.rb +0 -10
  18. data/lib/synvert/core/version.rb +1 -1
  19. data/lib/synvert/core.rb +4 -6
  20. data/spec/synvert/core/engine/erb_spec.rb +3 -3
  21. data/spec/synvert/core/node_ext_spec.rb +0 -795
  22. data/spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb +21 -1
  23. data/spec/synvert/core/rewriter/instance_spec.rb +47 -115
  24. data/spec/synvert/core/rewriter/scope/goto_scope_spec.rb +1 -4
  25. data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +1 -4
  26. data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +1 -4
  27. data/synvert-core-ruby.gemspec +4 -2
  28. metadata +44 -61
  29. data/lib/synvert/core/array_ext.rb +0 -48
  30. data/lib/synvert/core/node_query/compiler/array.rb +0 -34
  31. data/lib/synvert/core/node_query/compiler/attribute.rb +0 -39
  32. data/lib/synvert/core/node_query/compiler/attribute_list.rb +0 -24
  33. data/lib/synvert/core/node_query/compiler/basic_selector.rb +0 -28
  34. data/lib/synvert/core/node_query/compiler/boolean.rb +0 -23
  35. data/lib/synvert/core/node_query/compiler/comparable.rb +0 -86
  36. data/lib/synvert/core/node_query/compiler/dynamic_attribute.rb +0 -51
  37. data/lib/synvert/core/node_query/compiler/expression.rb +0 -41
  38. data/lib/synvert/core/node_query/compiler/float.rb +0 -23
  39. data/lib/synvert/core/node_query/compiler/identifier.rb +0 -41
  40. data/lib/synvert/core/node_query/compiler/integer.rb +0 -23
  41. data/lib/synvert/core/node_query/compiler/invalid_operator_error.rb +0 -7
  42. data/lib/synvert/core/node_query/compiler/nil.rb +0 -23
  43. data/lib/synvert/core/node_query/compiler/parse_error.rb +0 -7
  44. data/lib/synvert/core/node_query/compiler/regexp.rb +0 -37
  45. data/lib/synvert/core/node_query/compiler/selector.rb +0 -113
  46. data/lib/synvert/core/node_query/compiler/string.rb +0 -23
  47. data/lib/synvert/core/node_query/compiler/symbol.rb +0 -23
  48. data/lib/synvert/core/node_query/compiler.rb +0 -25
  49. data/lib/synvert/core/node_query/lexer.rex +0 -99
  50. data/lib/synvert/core/node_query/lexer.rex.rb +0 -299
  51. data/lib/synvert/core/node_query/parser.racc.rb +0 -306
  52. data/lib/synvert/core/node_query/parser.y +0 -60
  53. data/lib/synvert/core/node_query.rb +0 -36
  54. data/lib/synvert/core/rewriter/action/append_action.rb +0 -28
  55. data/lib/synvert/core/rewriter/action/delete_action.rb +0 -34
  56. data/lib/synvert/core/rewriter/action/insert_action.rb +0 -34
  57. data/lib/synvert/core/rewriter/action/insert_after_action.rb +0 -22
  58. data/lib/synvert/core/rewriter/action/prepend_action.rb +0 -44
  59. data/lib/synvert/core/rewriter/action/remove_action.rb +0 -56
  60. data/lib/synvert/core/rewriter/action/replace_action.rb +0 -33
  61. data/lib/synvert/core/rewriter/action/replace_with_action.rb +0 -36
  62. data/lib/synvert/core/rewriter/action/wrap_action.rb +0 -37
  63. data/lib/synvert/core/rewriter/action.rb +0 -102
  64. data/spec/synvert/core/node_query/lexer_spec.rb +0 -580
  65. data/spec/synvert/core/node_query/parser_spec.rb +0 -337
  66. data/spec/synvert/core/rewriter/action/append_action_spec.rb +0 -70
  67. data/spec/synvert/core/rewriter/action/delete_action_spec.rb +0 -26
  68. data/spec/synvert/core/rewriter/action/insert_action_spec.rb +0 -70
  69. data/spec/synvert/core/rewriter/action/insert_after_action_spec.rb +0 -26
  70. data/spec/synvert/core/rewriter/action/prepend_action_spec.rb +0 -175
  71. data/spec/synvert/core/rewriter/action/remove_action_spec.rb +0 -26
  72. data/spec/synvert/core/rewriter/action/replace_action_spec.rb +0 -28
  73. data/spec/synvert/core/rewriter/action/replace_with_action_spec.rb +0 -59
  74. data/spec/synvert/core/rewriter/action/wrap_action_spec.rb +0 -31
  75. data/spec/synvert/core/rewriter/action_spec.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 741ca9c2f6f29e5bbafbc5b63d94b3cd9a56aa20e8a00f3f70830b73b1fb697e
4
- data.tar.gz: a8bbf6e0c48a4af42578abb20807f3d86359fc069dc85ff90e12cf011f076998
3
+ metadata.gz: 71ae91a324677995dbfd9b1251ebf2a0a01e7c25289dcebcf86abb07599b1db8
4
+ data.tar.gz: 4370235d14aee70f57b6b02313637e9d24b13ca2aee61b71e4fa4022f78bc3f8
5
5
  SHA512:
6
- metadata.gz: 7fcadf632c863b1f3ba410b65f63c741b594255567f337ebc86c51ae45e681484653b45eec01fc5c3e3a4ea170a6bd38e899bdf22f65b2e980d58cac8c11cfcd
7
- data.tar.gz: 80ebe8f07ef9679c6921233d52b46979a6bfb895e4b63b974672dec193ef52ce08c40454d2a92fd509f12b8f3567065bb7d2dbee33af7bca37a96246e6373381
6
+ metadata.gz: 8bcd68a69575a6cd5c5c0bc7a91f82d09d2f438ab06988c01ad14c7d97c863bc2556f5c3ad7d054e35cfcb830cb778ec10a9797952a56a9391062b4bf3ce2a3f
7
+ data.tar.gz: be7b4c9fda8428c0d2a8c29350f6d2c60c40577c0f990ed5d8f4d2742fc2545fc8ddbd139298aaf39a9e69e9e9bf83fe29385745ac7ef10459da836572df9327
data/.gitignore CHANGED
@@ -15,7 +15,3 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
-
19
- lib/synvert/core/node_query/lexer.rex.rb
20
- lib/synvert/core/node_query/parser.racc.rb
21
- lib/synvert/core/node_query/parser.output
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.5.0 (2022-07-02)
4
+
5
+ * Abstract `node_query`
6
+ * Abstract `node_mutation`
7
+ * Abstract `parser_node_ext`
8
+
3
9
  ## 1.4.0 (2022-05-21)
4
10
 
5
11
  * Drop support `:first-child` and `:last-child`
data/Gemfile CHANGED
@@ -7,9 +7,6 @@ gemspec
7
7
 
8
8
  gem "guard"
9
9
  gem "guard-rspec"
10
- gem "guard-rake"
11
- gem "oedipus_lex"
12
- gem "racc"
13
10
  gem "rake"
14
11
  gem "rspec"
15
12
  gem "rspec-mocks"
data/Guardfile CHANGED
@@ -3,14 +3,5 @@
3
3
  guard :rspec, cmd: 'bundle exec rspec' do
4
4
  watch(%r{^spec/.+_spec\.rb$})
5
5
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
6
- watch('lib/synvert/core/node_query/lexer.rex.rb') { 'spec/synvert/core/node_query/lexer_spec.rb' }
7
- watch('lib/synvert/core/node_query/compiler.rb') { 'spec/synvert/core/node_query/parser_spec.rb' }
8
- watch(%r{^lib/synvert/core/node_query/compiler/.*\.rb$}) { 'spec/synvert/core/node_query/parser_spec.rb' }
9
- watch('lib/synvert/core/node_query/parser.racc.rb') { 'spec/synvert/core/node_query/parser_spec.rb' }
10
6
  watch('spec/spec_helper.rb') { "spec" }
11
7
  end
12
-
13
- guard :rake, task: 'generate' do
14
- watch('lib/synvert/core/node_query/lexer.rex')
15
- watch('lib/synvert/core/node_query/parser.y')
16
- end
data/README.md CHANGED
@@ -8,29 +8,46 @@
8
8
  Synvert core provides a set of DSLs to rewrite ruby code. e.g.
9
9
 
10
10
  ```ruby
11
- Synvert::Rewriter.new 'ruby', 'map_and_flatten_to_flat_map' do
11
+ Synvert::Rewriter.new 'factory_bot', 'convert_factory_girl_to_factory_bot' do
12
12
  description <<~EOS
13
- It converts `map` and `flatten` to `flat_map`
13
+ It converts FactoryGirl to FactoryBot
14
14
 
15
15
  ```ruby
16
- enum.map do
17
- # do something
18
- end.flatten
16
+ require 'factory_girl'
17
+ require 'factory_girl_rails'
19
18
  ```
20
19
 
21
20
  =>
22
21
 
23
22
  ```ruby
24
- enum.flat_map do
25
- # do something
26
- end
23
+ require 'factory_bot'
24
+ require 'factory_bot_rails'
25
+ ```
26
+
27
+ ```ruby
28
+ FactoryGirl.create(:user)
29
+ FactoryGirl.build(:user)
30
+ ```
31
+
32
+ =>
33
+
34
+ ```ruby
35
+ FactoryBot.create(:user)
36
+ FactoryBot.build(:user)
27
37
  ```
28
38
  EOS
29
39
 
30
- within_files Synvert::ALL_RUBY_FILES do
31
- with_node type: 'send', receiver: { type: 'block', caller: { type: 'send', message: 'map' } }, message: 'flatten', arguments: { size: 0 } do
32
- delete :message, :dot
33
- replace 'receiver.caller.message', with: 'flat_map'
40
+ within_files Synvert::RAILS_TEST_FILES do
41
+ find_node '.const[name=FactoryGirl]' do
42
+ replace_with 'FactoryBot'
43
+ end
44
+
45
+ find_node ".send[receiver=nil][message=require][arguments.size=1][arguments.first='factory_girl']" do
46
+ replace :arguments, with: "'factory_bot'"
47
+ end
48
+
49
+ with_node type: 'send', receiver: nil, message: 'require', arguments: { size: 1, first: "'factory_girl_rails'" } do
50
+ replace :arguments, with: "'factory_bot_rails'"
34
51
  end
35
52
  end
36
53
  end
@@ -56,6 +73,7 @@ DSLs are as follows
56
73
 
57
74
  Scopes:
58
75
 
76
+ * [find_node](./Synvert/Core/Rewriter/Instance.html#find_node-instance_method) - recursively find matching ast nodes by node query language
59
77
  * [within_node](./Synvert/Core/Rewriter/Instance.html#within_node-instance_method) - recursively find matching ast nodes
60
78
  * [with_node](./Synvert/Core/Rewriter/Instance.html#with_node-instance_method) - alias to within_node
61
79
  * [goto_node](./Synvert/Core/Rewriter/Instance.html#goto_node-instance_method) - go to a child node
data/Rakefile CHANGED
@@ -2,21 +2,7 @@
2
2
 
3
3
  require "bundler/gem_tasks"
4
4
  require 'rspec/core/rake_task'
5
- RSpec::Core::RakeTask.new(:spec)
6
- require 'oedipus_lex'
7
- Rake.application.rake_require "oedipus_lex"
8
-
9
- file "lib/synvert/core/node_query/lexer.rex.rb" => "lib/synvert/core/node_query/lexer.rex"
10
- file "lib/synvert/core/node_query/parser.racc.rb" => "lib/synvert/core/node_query/parser.y"
11
5
 
12
- task :lexer => "lib/synvert/core/node_query/lexer.rex.rb"
13
- task :parser => "lib/synvert/core/node_query/parser.racc.rb"
14
- task :generate => [:lexer, :parser]
15
-
16
- rule '.racc.rb' => '.y' do |t|
17
- cmd = "bundle exec racc -l -v -o #{t.name} #{t.source}"
18
- sh cmd
19
- end
6
+ RSpec::Core::RakeTask.new(:spec)
20
7
 
21
8
  task :default => :spec
22
- task :spec => :generate
@@ -7,7 +7,7 @@ module Synvert::Core
7
7
  ERUBY_EXPR_SPLITTER = '; ;'
8
8
  ERUBY_STMT_SPLITTER = '; ;'
9
9
 
10
- class ERB
10
+ class Erb
11
11
  class << self
12
12
  # convert erb to ruby code.
13
13
  #
@@ -3,6 +3,6 @@
3
3
  module Synvert::Core
4
4
  # Engine defines how to encode / decode other files (like erb).
5
5
  module Engine
6
- autoload :ERB, 'synvert/core/engine/erb'
6
+ autoload :Erb, 'synvert/core/engine/erb'
7
7
  end
8
8
  end
@@ -29,311 +29,6 @@ module Parser::AST
29
29
  # Source Code to Ast Node
30
30
  # {https://synvert-playground.xinminlabs.com/ruby}
31
31
  class Node
32
- TYPE_CHILDREN = {
33
- and: %i[left_value right_value],
34
- arg: %i[name],
35
- begin: %i[body],
36
- block: %i[caller arguments body],
37
- blockarg: %i[name],
38
- const: %i[parent_const name],
39
- class: %i[name parent_class body],
40
- csend: %i[receiver message arguments],
41
- cvasgn: %i[left_value right_value],
42
- cvar: %i[name],
43
- def: %i[name arguments body],
44
- definded?: %i[arguments],
45
- defs: %i[self name arguments body],
46
- hash: %i[pairs],
47
- ivasgn: %i[left_value right_value],
48
- ivar: %i[name],
49
- lvar: %i[name],
50
- lvasgn: %i[left_value right_value],
51
- masgn: %i[left_value right_value],
52
- module: %i[name body],
53
- or: %i[left_value right_value],
54
- or_asgn: %i[left_value right_value],
55
- pair: %i[key value],
56
- restarg: %i[name],
57
- send: %i[receiver message arguments],
58
- super: %i[arguments],
59
- zsuper: %i[]
60
- }
61
-
62
- # Initialize a Node.
63
- #
64
- # It extends {Parser::AST::Node} and set parent for its child nodes.
65
- def initialize(type, children = [], properties = {})
66
- @mutable_attributes = {}
67
- super
68
- # children could be nil for s(:array)
69
- Array(children).each do |child_node|
70
- if child_node.is_a?(Parser::AST::Node)
71
- child_node.parent = self
72
- end
73
- end
74
- end
75
-
76
- # Get the parent node.
77
- # @return [Parser::AST::Node] parent node.
78
- def parent
79
- @mutable_attributes[:parent]
80
- end
81
-
82
- # Set the parent node.
83
- # @param node [Parser::AST::Node] parent node.
84
- def parent=(node)
85
- @mutable_attributes[:parent] = node
86
- end
87
-
88
- # Get the sibling nodes.
89
- # @return [Array<Parser::AST::Node>] sibling nodes.
90
- def siblings
91
- index = parent.children.index(self)
92
- parent.children[index + 1..]
93
- end
94
-
95
- # Dyamically defined method
96
- # caller, key, left_value, message, name, pairs, parent_class, parent_const, receivr, rgith_value and value.
97
- # based on const TYPE_CHILDREN.
98
- %i[
99
- caller
100
- key
101
- left_value
102
- message
103
- name
104
- pairs
105
- parent_class
106
- parent_const
107
- receiver
108
- right_value
109
- value
110
- ].each do |method_name|
111
- define_method(method_name) do
112
- index = TYPE_CHILDREN[type]&.index(method_name)
113
- return children[index] if index
114
-
115
- raise Synvert::Core::MethodNotSupported, "#{method_name} is not handled for #{debug_info}"
116
- end
117
- end
118
-
119
- # Return the left value of node.
120
- # It supports :and, :cvagn, :lvasgn, :masgn, :or and :or_asgn nodes.
121
- # @example
122
- # node # s(:or_asgn, s(:lvasgn, :a), s(:int, 1))
123
- # node.left_value # :a
124
- # @return [Parser::AST::Node] left value of node.
125
- # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
126
- def left_value
127
- return children[0].children[0] if type == :or_asgn
128
-
129
- index = TYPE_CHILDREN[type]&.index(:left_value)
130
- return children[index] if index
131
-
132
- raise Synvert::Core::MethodNotSupported, "#{left_value} is not handled for #{debug_info}"
133
- end
134
-
135
- # Get arguments of node.
136
- # It supports :block, :csend, :def, :defined?, :defs and :send nodes.
137
- # @example
138
- # node # s(:send, s(:const, nil, :FactoryGirl), :create, s(:sym, :post), s(:hash, s(:pair, s(:sym, :title), s(:str, "post"))))
139
- # node.arguments # [s(:sym, :post), s(:hash, s(:pair, s(:sym, :title), s(:str, "post")))]
140
- # @return [Array<Parser::AST::Node>] arguments of node.
141
- # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
142
- def arguments
143
- case type
144
- when :def, :block
145
- children[1].children
146
- when :defs
147
- children[2].children
148
- when :send, :csend
149
- children[2..-1]
150
- when :defined?
151
- children
152
- else
153
- raise Synvert::Core::MethodNotSupported, "arguments is not handled for #{debug_info}"
154
- end
155
- end
156
-
157
- # Get body of node.
158
- # It supports :begin, :block, :class, :def, :defs and :module node.
159
- # @example
160
- # node # s(:block, s(:send, s(:const, nil, :RSpec), :configure), s(:args, s(:arg, :config)), s(:send, nil, :include, s(:const, s(:const, nil, :EmailSpec), :Helpers)))
161
- # node.body # [s(:send, nil, :include, s(:const, s(:const, nil, :EmailSpec), :Helpers))]
162
- # @return [Array<Parser::AST::Node>] body of node.
163
- # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
164
- def body
165
- case type
166
- when :begin
167
- children
168
- when :def, :block, :class, :module
169
- return [] if children[2].nil?
170
-
171
- :begin == children[2].type ? children[2].body : children[2..-1]
172
- when :defs
173
- return [] if children[3].nil?
174
-
175
- :begin == children[3].type ? children[3].body : children[3..-1]
176
- else
177
- raise Synvert::Core::MethodNotSupported, "body is not handled for #{debug_info}"
178
- end
179
- end
180
-
181
- # Get condition of node.
182
- # It supports :if node.
183
- # @example
184
- # node # s(:if, s(:defined?, s(:const, nil, :Bundler)), nil, nil)
185
- # node.condition # s(:defined?, s(:const, nil, :Bundler))
186
- # @return [Parser::AST::Node] condition of node.
187
- # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
188
- def condition
189
- if :if == type
190
- children[0]
191
- else
192
- raise Synvert::Core::MethodNotSupported, "condition is not handled for #{debug_info}"
193
- end
194
- end
195
-
196
- # Get keys of :hash node.
197
- # @example
198
- # node # s(:hash, s(:pair, s(:sym, :foo), s(:sym, :bar)), s(:pair, s(:str, "foo"), s(:str, "bar")))
199
- # node.keys # [s(:sym, :foo), s(:str, "foo")]
200
- # @return [Array<Parser::AST::Node>] keys of node.
201
- # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
202
- def keys
203
- if :hash == type
204
- children.map { |child| child.children[0] }
205
- else
206
- raise Synvert::Core::MethodNotSupported, "keys is not handled for #{debug_info}"
207
- end
208
- end
209
-
210
- # Get values of :hash node.
211
- # @example
212
- # node # s(:hash, s(:pair, s(:sym, :foo), s(:sym, :bar)), s(:pair, s(:str, "foo"), s(:str, "bar")))
213
- # node.values # [s(:sym, :bar), s(:str, "bar")]
214
- # @return [Array<Parser::AST::Node>] values of node.
215
- # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
216
- def values
217
- if :hash == type
218
- children.map { |child| child.children[1] }
219
- else
220
- raise Synvert::Core::MethodNotSupported, "keys is not handled for #{debug_info}"
221
- end
222
- end
223
-
224
- # Check if :hash node contains specified key.
225
- # @example
226
- # node # s(:hash, s(:pair, s(:sym, :foo), s(:sym, :bar)))
227
- # node.key?(:foo) # true
228
- # @param [Symbol, String] key value.
229
- # @return [Boolean] true if specified key exists.
230
- # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
231
- def key?(key)
232
- if :hash == type
233
- children.any? { |pair_node| pair_node.key.to_value == key }
234
- else
235
- raise Synvert::Core::MethodNotSupported, "key? is not handled for #{debug_info}"
236
- end
237
- end
238
-
239
- # Get :hash value node according to specified key.
240
- # @example
241
- # node # s(:hash, s(:pair, s(:sym, :foo), s(:sym, :bar)))
242
- # node.hash_value(:foo) # s(:sym, :bar)
243
- # @param [Symbol, String] key value.
244
- # @return [Parser::AST::Node] hash value of node.
245
- # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
246
- def hash_value(key)
247
- if :hash == type
248
- value_node = children.find { |pair_node| pair_node.key.to_value == key }
249
- value_node&.value
250
- else
251
- raise Synvert::Core::MethodNotSupported, "hash_value is not handled for #{debug_info}"
252
- end
253
- end
254
-
255
- # Return the exact value of node.
256
- # It supports :array, :begin, :erange, :false, :float, :irange, :int, :str, :sym and :true nodes.
257
- # @example
258
- # node # s(:array, s(:str, "str"), s(:sym, :str))
259
- # node.to_value # ['str', :str]
260
- # @return [Object] exact value.
261
- # @raise [Synvert::Core::MethodNotSupported] if calls on other node.
262
- def to_value
263
- case type
264
- when :int, :float, :str, :sym
265
- children.last
266
- when :true
267
- true
268
- when :false
269
- false
270
- when :nil
271
- nil
272
- when :array
273
- children.map(&:to_value)
274
- when :irange
275
- (children.first.to_value..children.last.to_value)
276
- when :erange
277
- (children.first.to_value...children.last.to_value)
278
- when :begin
279
- children.first.to_value
280
- else
281
- self
282
- end
283
- end
284
-
285
- # Respond key value and source for hash node, e.g.
286
- # @example
287
- # node # s(:hash, s(:pair, s(:sym, :foo), s(:sym, :bar)))
288
- # node.foo_value # :bar
289
- # node.foo_source # ":bar"
290
- def method_missing(method_name, *args, &block)
291
- if :args == type && children.respond_to?(method_name)
292
- return children.send(method_name, *args, &block)
293
- elsif :hash == type && method_name.to_s.include?('_value')
294
- key = method_name.to_s.sub('_value', '')
295
- return hash_value(key.to_sym)&.to_value if key?(key.to_sym)
296
- return hash_value(key.to_s)&.to_value if key?(key.to_s)
297
-
298
- return nil
299
- elsif :hash == type && method_name.to_s.include?('_source')
300
- key = method_name.to_s.sub('_source', '')
301
- return hash_value(key.to_sym)&.to_source if key?(key.to_sym)
302
- return hash_value(key.to_s)&.to_source if key?(key.to_s)
303
-
304
- return nil
305
- end
306
-
307
- super
308
- end
309
-
310
- def respond_to_missing?(method_name, *args)
311
- if :args == type && children.respond_to?(method_name)
312
- return true
313
- elsif :hash == type && method_name.to_s.include?('_value')
314
- key = method_name.to_s.sub('_value', '')
315
- return true if key?(key.to_sym) || key?(key.to_s)
316
- elsif :hash == type && method_name.to_s.include?('_source')
317
- key = method_name.to_s.sub('_source', '')
318
- return true if key?(key.to_sym) || key?(key.to_s)
319
- end
320
-
321
- super
322
- end
323
-
324
- # Return the debug info.
325
- #
326
- # @return [String] file, line, source and node.
327
- def debug_info
328
- "\n" +
329
- [
330
- "file: #{loc.expression.source_buffer.name}",
331
- "line: #{loc.expression.line}",
332
- "source: #{to_source}",
333
- "node: #{inspect}"
334
- ].join("\n")
335
- end
336
-
337
32
  # Get the file name of node.
338
33
  #
339
34
  # @return [String] file name.
@@ -341,13 +36,6 @@ module Parser::AST
341
36
  loc.expression&.source_buffer.name
342
37
  end
343
38
 
344
- # Get the source code of node.
345
- #
346
- # @return [String] source code.
347
- def to_source
348
- loc.expression&.source
349
- end
350
-
351
39
  # Get the column of node.
352
40
  #
353
41
  # @return [Integer] column.
@@ -362,113 +50,6 @@ module Parser::AST
362
50
  loc.expression.line
363
51
  end
364
52
 
365
- # Get child node by the name.
366
- #
367
- # @param child_name [String] name of child node.
368
- # @return [Parser::AST::Node] the child node.
369
- def child_node_by_name(child_name)
370
- direct_child_name, nested_child_name = child_name.to_s.split('.', 2)
371
- if respond_to?(direct_child_name)
372
- child_node = send(direct_child_name)
373
-
374
- return child_node.child_node_by_name(nested_child_name) if nested_child_name
375
-
376
- return nil if child_node.nil?
377
-
378
- return child_node if child_node.is_a?(Parser::AST::Node)
379
-
380
- return child_node
381
- end
382
-
383
- raise Synvert::Core::MethodNotSupported,
384
- "child_node_by_name is not handled for #{debug_info}, child_name: #{child_name}"
385
- end
386
-
387
- # Get the source range of child node.
388
- #
389
- # @param child_name [String] name of child node.
390
- # @return [Parser::Source::Range] source range of child node.
391
- def child_node_range(child_name)
392
- case [type, child_name.to_sym]
393
- when %i[block pipes], %i[def parentheses], %i[defs parentheses]
394
- Parser::Source::Range.new(
395
- '(string)',
396
- arguments.first.loc.expression.begin_pos - 1,
397
- arguments.last.loc.expression.end_pos + 1
398
- )
399
- when %i[block arguments], %i[def arguments], %i[defs arguments]
400
- Parser::Source::Range.new(
401
- '(string)',
402
- arguments.first.loc.expression.begin_pos,
403
- arguments.last.loc.expression.end_pos
404
- )
405
- when %i[class name], %i[def name], %i[defs name]
406
- loc.name
407
- when %i[defs dot]
408
- loc.operator
409
- when %i[defs self]
410
- Parser::Source::Range.new('(string)', loc.operator.begin_pos - 'self'.length, loc.operator.begin_pos)
411
- when %i[send dot], %i[csend dot]
412
- loc.dot
413
- when %i[send message], %i[csend message]
414
- if loc.operator
415
- Parser::Source::Range.new('(string)', loc.selector.begin_pos, loc.operator.end_pos)
416
- else
417
- loc.selector
418
- end
419
- when %i[send parentheses], %i[csend parentheses]
420
- if loc.begin && loc.end
421
- Parser::Source::Range.new('(string)', loc.begin.begin_pos, loc.end.end_pos)
422
- end
423
- else
424
- direct_child_name, nested_child_name = child_name.to_s.split('.', 2)
425
- if respond_to?(direct_child_name)
426
- child_node = send(direct_child_name)
427
-
428
- return child_node.child_node_range(nested_child_name) if nested_child_name
429
-
430
- return nil if child_node.nil?
431
-
432
- if child_node.is_a?(Parser::AST::Node)
433
- return(
434
- Parser::Source::Range.new(
435
- '(string)',
436
- child_node.loc.expression.begin_pos,
437
- child_node.loc.expression.end_pos
438
- )
439
- )
440
- end
441
-
442
- # arguments
443
- return nil if child_node.empty?
444
-
445
- return(
446
- Parser::Source::Range.new(
447
- '(string)',
448
- child_node.first.loc.expression.begin_pos,
449
- child_node.last.loc.expression.end_pos
450
- )
451
- )
452
- end
453
-
454
- raise Synvert::Core::MethodNotSupported,
455
- "child_node_range is not handled for #{debug_info}, child_name: #{child_name}"
456
- end
457
- end
458
-
459
- # Recursively iterate all child nodes of node.
460
- #
461
- # @yield [child] Gives a child node.
462
- # @yieldparam child [Parser::AST::Node] child node
463
- def recursive_children(&block)
464
- children.each do |child|
465
- if child.is_a?(Parser::AST::Node)
466
- stop = yield child
467
- child.recursive_children(&block) unless stop == :stop
468
- end
469
- end
470
- end
471
-
472
53
  # Match node with rules.
473
54
  # It provides some additional keywords to match rules, +any+, +contain+, +not+, +in+, +not_in+, +gt+, +gte+, +lt+, +lte+.
474
55
  # @example
@@ -506,53 +87,6 @@ module Parser::AST
506
87
  end
507
88
  end
508
89
 
509
- # Get rewritten source code.
510
- # @example
511
- # node.rewritten_source("create({{arguments}})") # "create(:post)"
512
- # @param code [String] raw code.
513
- # @return [String] rewritten code, replace string in block !{{ }} in raw code.
514
- # @raise [Synvert::Core::MethodNotSupported] if string in block !{{ }} does not support.
515
- def rewritten_source(code)
516
- code.gsub(/{{(.*?)}}/m) do
517
- old_code = Regexp.last_match(1)
518
- if respond_to?(old_code.split('.').first)
519
- evaluated = child_node_by_name(old_code)
520
- case evaluated
521
- when Parser::AST::Node
522
- if evaluated.type == :args
523
- evaluated.loc.expression.source[1...-1]
524
- else
525
- evaluated.loc.expression.source
526
- end
527
- when Array
528
- if evaluated.size > 0
529
- file_source = evaluated.first.loc.expression.source_buffer.source
530
- source = file_source[evaluated.first.loc.expression.begin_pos...evaluated.last.loc.expression.end_pos]
531
- lines = source.split "\n"
532
- lines_count = lines.length
533
- if lines_count > 1 && lines_count == evaluated.size
534
- new_code = []
535
- lines.each_with_index { |line, index|
536
- new_code << (index == 0 ? line : line[evaluated.first.indent - 2..-1])
537
- }
538
- new_code.join("\n")
539
- else
540
- source
541
- end
542
- end
543
- when String, Symbol, Integer, Float
544
- evaluated
545
- when NilClass
546
- 'nil'
547
- else
548
- raise Synvert::Core::MethodNotSupported, "rewritten_source is not handled for #{evaluated.inspect}"
549
- end
550
- else
551
- "{{#{old_code}}}"
552
- end
553
- end
554
- end
555
-
556
90
  # Strip curly braces for hash.
557
91
  # @example
558
92
  # node # s(:hash, s(:pair, s(:sym, :foo), s(:str, "bar")))