parser_node_ext 0.11.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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