synvert-core 1.4.0 → 1.5.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 (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")))