parser_node_ext 0.11.0 → 1.1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 935089d050b6cfa37cb4b2b73aa2f2b29fc82b6e355354a46184f20434a331e2
4
- data.tar.gz: d1667479f06fb825d9abe9479dbc4eacc64a234e72c792709f6735fab02e56c2
3
+ metadata.gz: 9c326faea53723b13d4a991011fb260e874a0d86788308c4c4a919ede8d5680b
4
+ data.tar.gz: 1892e4c21ec1e1c8d4f2fc8c8b4cc78f502a8d20bcf4ee3cd823aa717415122e
5
5
  SHA512:
6
- metadata.gz: fcdf61c369ee2486b3eb276714f38ad53a75e022732fdfcbd9d38f0d05615efd4268813d675e9548e5ba27c8b020f8a5c88e472b48ad317c558c23c2e566f824
7
- data.tar.gz: b98d563672fab7af70592839603b7ac7a3d0315710d11b2a071a9b66a84f9d5744df3682277ed9a997f172f84031c4417112ca38e7be267f1383b6a21e8bbaf9
6
+ metadata.gz: 810a25e6c68cfc13791501a5bf1d7a3264a31a90b4af25ba4d109373bd18240fa88c577a194540ebb7835da756e0f1ad584ad19d6318165e802c68e49167b6eb
7
+ data.tar.gz: cba51e45acbf600057a22ac27fd21fe1a980fc6d7b8278312815c4b8c87dd89ab7b9b2b67af81994078f4dd4cf8f34e0755ef59357ee090cc0852a87740b1b26
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.1.0 (2023-05-15)
4
+
5
+ * hash `xxx_value` returns the node rather than the value
6
+ * Support `xxx_pair` for `hash` node
7
+
8
+ ## 1.0.0 (2023-02-12)
9
+
10
+ * Support almost all of nodes
11
+
3
12
  ## 0.11.0 (2023-02-12)
4
13
 
5
14
  * Support `self` node
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- parser_node_ext (0.11.0)
4
+ parser_node_ext (1.1.0)
5
5
  parser
6
6
 
7
7
  GEM
@@ -9,7 +9,7 @@ GEM
9
9
  specs:
10
10
  ast (2.4.2)
11
11
  diff-lcs (1.5.0)
12
- parser (3.2.1.0)
12
+ parser (3.2.2.1)
13
13
  ast (~> 2.4.1)
14
14
  rake (13.0.6)
15
15
  rspec (3.11.0)
data/README.md CHANGED
@@ -1,8 +1,15 @@
1
1
  # ParserNodeExt
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/parser_node_ext`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ It assigns names to the child nodes of the [parser](https://rubygems.org/gems/parser).
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ It also adds some helpers
6
+
7
+ ```ruby
8
+ # node is a hash node
9
+ node.foo_pair # get the pair node of hash foo key
10
+ node.foo_value # get the value node of the hash foo key
11
+ node.foo_source # get the source of the value node of the hash foo key
12
+ ```
6
13
 
7
14
  ## Installation
8
15
 
@@ -22,7 +29,10 @@ Or install it yourself as:
22
29
 
23
30
  ## Usage
24
31
 
25
- TODO: Write usage instructions here
32
+ ```ruby
33
+ require 'parser/current'
34
+ require 'parser_node_ext'
35
+ ```
26
36
 
27
37
  ## Development
28
38
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ParserNodeExt
4
- VERSION = "0.11.0"
4
+ VERSION = "1.1.0"
5
5
  end
@@ -9,60 +9,111 @@ module ParserNodeExt
9
9
  # Your code goes here...
10
10
 
11
11
  TYPE_CHILDREN = {
12
+ alias: %i[new_name old_name],
12
13
  and: %i[left_value right_value],
14
+ and_asgn: %i[variable value],
13
15
  arg: %i[name],
14
16
  array: %i[elements],
15
17
  array_pattern: %i[elements],
18
+ array_pattern_with_tail: %i[elements],
19
+ back_ref: %i[name],
16
20
  begin: %i[body],
17
21
  block: %i[caller arguments body],
18
22
  blockarg: %i[name],
23
+ block_pass: %i[name],
24
+ break: %i[expression],
19
25
  case: %i[expression when_statements else_statement],
20
26
  case_match: %i[expression in_statements else_statement],
27
+ casgn: %i[parent_const name value],
28
+ cbase: %i[],
29
+ complex: %i[value],
21
30
  const: %i[parent_const name],
22
31
  class: %i[name parent_class body],
23
32
  csend: %i[receiver message arguments],
24
- cvasgn: %i[left_value right_value],
33
+ cvasgn: %i[variable value],
25
34
  cvar: %i[name],
26
35
  def: %i[name arguments body],
27
36
  defined?: %i[arguments],
28
37
  defs: %i[self name arguments body],
38
+ dstr: %i[elements],
39
+ dsym: %i[elements],
40
+ eflipflop: %i[begin end],
41
+ ensure: %i[body ensure_body],
29
42
  erange: %i[begin end],
30
43
  false: [],
31
44
  find_pattern: %i[elements],
32
45
  float: %i[value],
46
+ for: %i[variable expression body],
47
+ forward_args: [],
48
+ gvar: %i[name],
49
+ gvasgn: %i[variable value],
33
50
  hash: %i[pairs],
34
51
  hash_pattern: %i[pairs],
35
52
  if: %i[expression if_statement else_statement],
53
+ iflipflop: %i[begin end],
36
54
  if_guard: %i[expression],
37
55
  int: %i[value],
38
56
  in_pattern: %i[expression guard body],
39
57
  irange: %i[begin end],
40
- ivasgn: %i[left_value right_value],
58
+ ivasgn: %i[variable value],
41
59
  ivar: %i[name],
60
+ kwarg: %i[name],
61
+ kwbody: %i[body],
62
+ kwnilarg: [],
63
+ kwoptarg: %i[name value],
64
+ kwrestarg: %i[name],
65
+ kwsplat: %i[name],
42
66
  lvar: %i[name],
43
- lvasgn: %i[left_value right_value],
44
- masgn: %i[left_value right_value],
67
+ lvasgn: %i[variable value],
68
+ masgn: %i[variable value],
45
69
  match_as: %i[key value],
70
+ match_nil_pattern: [],
46
71
  match_pattern: %i[left_value right_value],
47
72
  match_pattern_p: %i[left_value right_value],
48
73
  match_rest: %i[variable],
49
74
  match_var: %i[name],
75
+ match_with_lvasgn: %i[left_value right_value],
76
+ mlhs: %i[elements],
50
77
  module: %i[name body],
78
+ next: %i[expression],
51
79
  nil: [],
80
+ nth_ref: %i[name],
52
81
  numblock: %i[caller arguments_count body],
82
+ optarg: %i[name value],
83
+ op_asgn: %i[variable operator value],
53
84
  or: %i[left_value right_value],
54
- or_asgn: %i[left_value right_value],
85
+ or_asgn: %i[variable value],
55
86
  pair: %i[key value],
56
- pin: %i[variable],
87
+ pin: %i[expression],
88
+ postexe: %i[body],
89
+ preexe: %i[body],
90
+ rational: %i[value],
91
+ redo: [],
92
+ regexp: %i[elements options],
93
+ regopt: %i[elements],
94
+ resbody: %i[exceptions variable body],
95
+ rescue: %i[body rescue_bodies else_statement],
57
96
  restarg: %i[name],
97
+ retry: [],
98
+ return: %i[expression],
99
+ sclass: %i[name body],
58
100
  self: [],
101
+ shadowarg: %i[name],
59
102
  send: %i[receiver message arguments],
103
+ splat: %i[name],
60
104
  str: %i[value],
61
105
  super: %i[arguments],
62
106
  sym: %i[value],
63
107
  true: [],
108
+ undef: %i[elements],
64
109
  unless_guard: %i[expression],
110
+ until: %i[expression body],
111
+ until_post: %i[expression body],
65
112
  when: %i[expression body],
113
+ while: %i[expression body],
114
+ while_post: %i[expression body],
115
+ xstr: %i[elements],
116
+ yield: %i[arguments],
66
117
  zsuper: []
67
118
  }
68
119
 
@@ -111,24 +162,8 @@ module ParserNodeExt
111
162
  end
112
163
  end
113
164
 
114
- # Return the left value of node.
115
- # It supports :and, :cvagn, :lvasgn, :masgn, :or and :or_asgn nodes.
116
- # @example
117
- # node # s(:or_asgn, s(:lvasgn, :a), s(:int, 1))
118
- # node.left_value # :a
119
- # @return [Parser::AST::Node] left value of node.
120
- # @raise [MethodNotSupported] if calls on other node.
121
- def left_value
122
- return children[0].children[0] if type == :or_asgn
123
-
124
- index = TYPE_CHILDREN[type]&.index(:left_value)
125
- return children[index] if index
126
-
127
- raise MethodNotSupported, "#{left_value} is not supported for #{self}"
128
- end
129
-
130
165
  # Get arguments of node.
131
- # It supports :block, :csend, :def, :defined?, :defs and :send nodes.
166
+ # It supports :block, :csend, :def, :defined?, :defs, :send, :yeild nodes.
132
167
  # @example
133
168
  # node # s(:send, s(:const, nil, :FactoryGirl), :create, s(:sym, :post), s(:hash, s(:pair, s(:sym, :title), s(:str, "post"))))
134
169
  # node.arguments # [s(:sym, :post), s(:hash, s(:pair, s(:sym, :title), s(:str, "post")))]
@@ -144,7 +179,7 @@ module ParserNodeExt
144
179
  children[1].children
145
180
  when :send, :csend
146
181
  children[2..-1]
147
- when :defined?
182
+ when :defined?, :yield
148
183
  children
149
184
  else
150
185
  raise MethodNotSupported, "arguments is not supported for #{self}"
@@ -152,7 +187,7 @@ module ParserNodeExt
152
187
  end
153
188
 
154
189
  # Get body of node.
155
- # It supports :begin, :block, :class, :def, :defs, :module, :numblock node.
190
+ # It supports :begin, :block, :class, :def, :defs, :ensure, :for, :module, :numblock, resbody, :sclass, :until, :until_post, :while and :while_post node.
156
191
  # @example
157
192
  # 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)))
158
193
  # node.body # [s(:send, nil, :include, s(:const, s(:const, nil, :EmailSpec), :Helpers))]
@@ -160,20 +195,24 @@ module ParserNodeExt
160
195
  # @raise [MethodNotSupported] if calls on other node.
161
196
  def body
162
197
  case type
163
- when :begin
198
+ when :begin, :kwbegin
164
199
  children
165
- when :when, :module
200
+ when :rescue, :ensure, :preexe, :postexe
201
+ return [] if children[0].nil?
202
+
203
+ [:begin, :kwbegin].include?(children[0].type) ? children[0].body : [children[0]]
204
+ when :when, :module, :sclass, :until, :until_post, :while, :while_post
166
205
  return [] if children[1].nil?
167
206
 
168
- :begin == children[1].type ? children[1].body : children[1..-1]
169
- when :def, :block, :class, :numblock, :in_pattern
207
+ [:begin, :kwbegin].include?(children[1].type) ? children[1].body : children[1..-1]
208
+ when :def, :block, :class, :for, :in_pattern, :numblock, :resbody
170
209
  return [] if children[2].nil?
171
210
 
172
- :begin == children[2].type ? children[2].body : children[2..-1]
211
+ [:begin, :kwbegin].include?(children[2].type) ? children[2].body : children[2..-1]
173
212
  when :defs
174
213
  return [] if children[3].nil?
175
214
 
176
- :begin == children[3].type ? children[3].body : children[3..-1]
215
+ [:begin, :kwbegin].include?(children[3].type) ? children[3].body : children[3..-1]
177
216
  else
178
217
  raise MethodNotSupported, "body is not supported for #{self}"
179
218
  end
@@ -190,6 +229,28 @@ module ParserNodeExt
190
229
  end
191
230
  end
192
231
 
232
+ # Get rescue bodies of resuce node.
233
+ # @return [Array<Parser::AST::Node>] rescue statements of rescue node.
234
+ # @raise [MethodNotSupported] if calls on other node.
235
+ def rescue_bodies
236
+ if :rescue == type
237
+ children[1...-1]
238
+ else
239
+ raise MethodNotSupported, "rescue_bodies is not supported for #{self}"
240
+ end
241
+ end
242
+
243
+ # Get ensure body of ensure node.
244
+ # @return [Array<Parser::AST::Node>] ensure body of ensure node.
245
+ # @raise [MethodNotSupported] if calls on other node.
246
+ def ensure_body
247
+ if :ensure == type
248
+ children[1..-1]
249
+ else
250
+ raise MethodNotSupported, "ensure_body is not supported for #{self}"
251
+ end
252
+ end
253
+
193
254
  # Get in statements of case_match node.
194
255
  # @return [Array<Parser::AST::Node>] in statements of case node.
195
256
  # @raise [MethodNotSupported] if calls on other node.
@@ -201,24 +262,54 @@ module ParserNodeExt
201
262
  end
202
263
  end
203
264
 
204
- # Get else statement of case node.
205
- # @return [Parser::AST::Node] else statement of case node.
265
+ # Get else statement of node.
266
+ # @return [Parser::AST::Node] else statement of node.
206
267
  # @raise [MethodNotSupported] if calls on other node.
207
268
  def else_statement
208
269
  children[-1]
209
270
  end
210
271
 
211
- # Get elements of :array and :array_pattern node.
272
+ # Get elements of :array, :array_pattern, :array_pattern_with_tail, :find_pattern, :dstr, :dsym, :xstr, :regopt, :mlhs and :undef node.
212
273
  # @return [Array<Parser::AST::Node>] elements of array node.
213
274
  # @raise [MethodNotSupported] if calls on other node.
214
275
  def elements
215
- if %i[array array_pattern find_pattern].include?(type)
276
+ if %i[array array_pattern array_pattern_with_tail find_pattern dstr dsym xstr regopt mlhs undef].include?(type)
216
277
  children
278
+ elsif type == :regexp
279
+ children[0...-1]
217
280
  else
218
281
  raise MethodNotSupported, "elements is not supported for #{self}"
219
282
  end
220
283
  end
221
284
 
285
+ # Get options of :regexp node.
286
+ # @example
287
+ # node # s(:regexp, s(:str, "foo"), s(:regopt, :i, :m))
288
+ # node.options # s(:regopt, :i, :m)
289
+ # @return [Parser::AST::Node] options of regexp node.
290
+ # @raise [MethodNotSupported] if calls on other node.
291
+ def options
292
+ if :regexp == type
293
+ children[-1]
294
+ else
295
+ raise MethodNotSupported, "options is not supported for #{self}"
296
+ end
297
+ end
298
+
299
+ # Get exceptions of :resbody node.
300
+ # @example
301
+ # node # s(:resbody, s(:array, (:const nil :Exception), (:const nil :A)), s(:lvasgn :bar), s(:int 1))
302
+ # node.exceptions # s(:array, (:const nil :Exception), (:const nil :A))
303
+ # @return [Parser::AST::Node] exceptions of resbody node.
304
+ # @raise [MethodNotSupported] if calls on other node.
305
+ def exceptions
306
+ if :resbody == type
307
+ children[0]
308
+ else
309
+ raise MethodNotSupported, "exceptions is not supported for #{self}"
310
+ end
311
+ end
312
+
222
313
  # Get pairs of :hash and :hash_pattern node.
223
314
  # @example
224
315
  # node # s(:hash, s(:pair, s(:sym, :foo), s(:sym, :bar)), s(:pair, s(:str, "foo"), s(:str, "bar")))
@@ -276,12 +367,27 @@ module ParserNodeExt
276
367
  end
277
368
  end
278
369
 
370
+ # Get :hash pair node according to specified key.
371
+ # @example
372
+ # node # s(:hash, s(:pair, s(:sym, :foo), s(:sym, :bar)))
373
+ # node.hash_pair(:foo) # s(:pair, s(:sym, :foo), s(:sym, :bar))
374
+ # @param [Symbol, String] key value.
375
+ # @return [Parser::AST::Node] hash pair node.
376
+ # @raise [MethodNotSupported] if calls on other node.
377
+ def hash_pair(key)
378
+ if :hash == type
379
+ children.find { |pair_node| pair_node.key.to_value == key }
380
+ else
381
+ raise MethodNotSupported, "hash_pair is not supported for #{self}"
382
+ end
383
+ end
384
+
279
385
  # Get :hash value node according to specified key.
280
386
  # @example
281
387
  # node # s(:hash, s(:pair, s(:sym, :foo), s(:sym, :bar)))
282
388
  # node.hash_value(:foo) # s(:sym, :bar)
283
389
  # @param [Symbol, String] key value.
284
- # @return [Parser::AST::Node] hash value of node.
390
+ # @return [Parser::AST::Node] hash value node.
285
391
  # @raise [MethodNotSupported] if calls on other node.
286
392
  def hash_value(key)
287
393
  if :hash == type
@@ -315,7 +421,7 @@ module ParserNodeExt
315
421
  (children.first.to_value..children.last.to_value)
316
422
  when :erange
317
423
  (children.first.to_value...children.last.to_value)
318
- when :begin
424
+ when :begin, :kwbegin
319
425
  children.first.to_value
320
426
  else
321
427
  self
@@ -359,18 +465,24 @@ module ParserNodeExt
359
465
  def method_missing(method_name, *args, &block)
360
466
  if :args == type && children.respond_to?(method_name)
361
467
  return children.send(method_name, *args, &block)
362
- elsif :hash == type && method_name.to_s.include?('_value')
363
- key = method_name.to_s.sub('_value', '')
364
- return hash_value(key.to_sym)&.to_value if key?(key.to_sym)
365
- return hash_value(key.to_s)&.to_value if key?(key.to_s)
468
+ elsif :hash == type && method_name.to_s.end_with?('_pair')
469
+ key = method_name.to_s[0..-6]
470
+ return hash_pair(key.to_sym) if key?(key.to_sym)
471
+ return hash_pair(key.to_s) if key?(key.to_s)
366
472
 
367
473
  return nil
368
- elsif :hash == type && method_name.to_s.include?('_source')
369
- key = method_name.to_s.sub('_source', '')
474
+ elsif :hash == type && method_name.to_s.end_with?('_value')
475
+ key = method_name.to_s[0..-7]
476
+ return hash_value(key.to_sym) if key?(key.to_sym)
477
+ return hash_value(key.to_s) if key?(key.to_s)
478
+
479
+ return nil
480
+ elsif :hash == type && method_name.to_s.end_with?('_source')
481
+ key = method_name.to_s[0..-8]
370
482
  return hash_value(key.to_sym)&.to_source if key?(key.to_sym)
371
483
  return hash_value(key.to_s)&.to_source if key?(key.to_s)
372
484
 
373
- return nil
485
+ return ''
374
486
  end
375
487
 
376
488
  super
@@ -379,12 +491,15 @@ module ParserNodeExt
379
491
  def respond_to_missing?(method_name, *args)
380
492
  if :args == type && children.respond_to?(method_name)
381
493
  return true
382
- elsif :hash == type && method_name.to_s.include?('_value')
383
- key = method_name.to_s.sub('_value', '')
384
- return true if key?(key.to_sym) || key?(key.to_s)
385
- elsif :hash == type && method_name.to_s.include?('_source')
386
- key = method_name.to_s.sub('_source', '')
387
- return true if key?(key.to_sym) || key?(key.to_s)
494
+ elsif :hash == type && method_name.to_s.end_with?('_pair')
495
+ key = method_name.to_s[0..-6]
496
+ return key?(key.to_sym) || key?(key.to_s)
497
+ elsif :hash == type && method_name.to_s.end_with?('_value')
498
+ key = method_name.to_s[0..-7]
499
+ return key?(key.to_sym) || key?(key.to_s)
500
+ elsif :hash == type && method_name.to_s.end_with?('_source')
501
+ key = method_name.to_s[0..-8]
502
+ return key?(key.to_sym) || key?(key.to_s)
388
503
  end
389
504
 
390
505
  super
@@ -9,8 +9,13 @@ module ParserNodeExt
9
9
  def caller: () -> Parser::AST::Node
10
10
  def elements: () -> Array[Parser::AST::Node]
11
11
  def else_statement: () -> Parser::AST::Node
12
+ def exceptions: () -> Array[Parser::AST::Node]
12
13
  def end: () -> Parser::AST::Node
14
+ def ensure_body: () -> Array[Parser::AST::Node]
13
15
  def expression: () -> Parser::AST::Node
16
+ def old_name: () -> Symbol
17
+ def options: () -> Parser::AST::Node
18
+ def operator: () -> Symbol
14
19
  def if_statement: () -> Parser::AST::Node
15
20
  def in_statements: () -> Array[Parser::AST::Node]
16
21
  def key: () -> Parser::AST::Node
@@ -18,9 +23,11 @@ module ParserNodeExt
18
23
  def left_value: () -> Parser::AST::Node | Symbol
19
24
  def message: () -> Symbol
20
25
  def name: () -> Parser::AST::Node | Symbol
26
+ def new_name: () -> Symbol
21
27
  def pairs: () -> Array[Parser::AST::Node]
22
28
  def parent_class: () -> Parser::AST::Node
23
29
  def receiver: () -> Parser::AST::Node
30
+ def rescue_bodies: () -> Array[Parser::AST::Node]
24
31
  def right_value: () -> Parser::AST::Node
25
32
  def self: () -> Parser::AST::Node
26
33
  def value: () -> Parser::AST::Node
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: parser_node_ext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-02-11 00:00:00.000000000 Z
11
+ date: 2023-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -63,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
63
  - !ruby/object:Gem::Version
64
64
  version: '0'
65
65
  requirements: []
66
- rubygems_version: 3.4.1
66
+ rubygems_version: 3.4.10
67
67
  signing_key:
68
68
  specification_version: 4
69
69
  summary: extend parser node