rensei 0.1.0 → 0.2.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: 6cc6cc047b5640e168c637b0dada84c773b645347a66385ad3fb06c7b7e08346
4
- data.tar.gz: 70800f0c78fadf6816b9b9762e5f26fd7be3a012515cd7b90149dd2d911149a3
3
+ metadata.gz: 7f251e1c901c50f3be916dc4adcb01598056cc5c86b0d65e1e592961b0ef3851
4
+ data.tar.gz: c36df6153e3c75d9f5c568a144d53e985715ab6703e7251c90cad1a16635fb7d
5
5
  SHA512:
6
- metadata.gz: c7cf2901a240748cfa044253a269a55154d0516829ccab38b166caa2ed8c5f4eed43589ec98aca49e2aaa9f629c7c6ef2736bf878c4de676daf1852d41f97dcc
7
- data.tar.gz: bdf5db3fd89679a2c5985b63a2905de5f2a7c42555264a53cb41ea3f24bbb0743fd2ed27a131e477d84c30ca3db6901099aa30242ed577b5bcbbbbefeefd5d53
6
+ metadata.gz: 8c63d7f42e0e767c21b70a57ef6954056a6f23134366bc84703f2ec2f23d7583dc1a7eb8dcfa64065497fb786209b466d6a48bdcc7258c1089ffdd1f77fe7fbc
7
+ data.tar.gz: 1a09797bffe2b6bd10cd9c663f54bd4bff56087d0c524e7f038da1da6baae7423b5876c9f750a07fcdc6585975aa24966ac580a0c39d6f830e06b8749455faff
@@ -0,0 +1,23 @@
1
+ name: Ruby CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ test:
7
+
8
+ runs-on: ubuntu-latest
9
+
10
+ strategy:
11
+ matrix:
12
+ ruby-version: [2.6.4, 2.7.0, 2.7.2, 3.0.1]
13
+
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - name: Set up Ruby ${{ matrix.ruby-version }}
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: ${{ matrix.ruby-version }}
20
+ - name: Install dependencies
21
+ run: bundle install
22
+ - name: Run tests
23
+ run: bundle exec rake
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Rensei
1
+ [![Ruby CI](https://github.com/osyo-manga/gem-rensei/actions/workflows/rensei.yml/badge.svg)](https://github.com/osyo-manga/gem-rensei/actions/workflows/rensei.yml)
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/rensei`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ # Rensei
4
4
 
5
5
  Unparse from `RubyVM::AbstractSyntaxTree::Node` to Ruby code.
6
6
 
@@ -46,7 +46,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
46
46
 
47
47
  ## Contributing
48
48
 
49
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rensei.
49
+ Bug reports and pull requests are welcome on GitHub at https://github.com/osyo-manga/gem-rensei.
50
50
 
51
51
 
52
52
  ## License
@@ -0,0 +1,9 @@
1
+ #!/bin/bash -ex
2
+ RBENV_VERSION=2.6.4 bundle install
3
+ RBENV_VERSION=2.7.0 bundle install
4
+ RBENV_VERSION=2.7.2 bundle install
5
+ RBENV_VERSION=2.7.3 bundle install
6
+ RBENV_VERSION=2.7.4 bundle install
7
+ RBENV_VERSION=3.0.0 bundle install
8
+ RBENV_VERSION=3.0.1 bundle install
9
+ RBENV_VERSION=3.1.0-dev bundle install
data/lib/rensei.rb CHANGED
@@ -5,7 +5,7 @@ require "rensei/node_to_hash"
5
5
  module Rensei
6
6
  class Error < StandardError; end
7
7
 
8
- def self.unparse(code)
9
- Unparser.unparse(code)
8
+ def self.unparse(code, opt = {})
9
+ Unparser.unparse(code, opt)
10
10
  end
11
11
  end
@@ -6,7 +6,7 @@ module Rensei
6
6
  using NodeToHash
7
7
  using Module.new {
8
8
  refine Object do
9
- def to_hashable
9
+ def to_h
10
10
  to_s
11
11
  end
12
12
  end
@@ -14,41 +14,26 @@ module Rensei
14
14
  NilClass,
15
15
  FalseClass,
16
16
  TrueClass,
17
- Array,
18
- Symbol,
19
17
  Numeric,
18
+ String,
19
+ Symbol,
20
+ Array,
20
21
  Regexp,
21
22
  ].each { |klass|
22
23
  refine klass do
23
- def to_hashable
24
+ def to_h
24
25
  self
25
26
  end
26
27
  end
27
28
  }
28
29
  }
29
30
 
30
- def to_hashable(ignore_codeposition: true, &block)
31
- block = :to_hashable unless block
31
+ def to_h
32
32
  {
33
33
  type: type,
34
- children: children.map(&block),
35
- }.tap { |it|
36
- it.merge!(
37
- first_column: first_column,
38
- last_column: last_column,
39
- first_lineno: first_lineno,
40
- last_lineno: last_lineno
41
- ) unless ignore_codeposition
34
+ children: children.map(&:to_h),
42
35
  }
43
36
  end
44
-
45
- def to_json(ignore_codeposition: true)
46
- to_hashable(ignore_codeposition: ignore_codeposition, &:to_json)
47
- end
48
-
49
- def to_h(ignore_codeposition: true)
50
- to_hashable(ignore_codeposition: ignore_codeposition)
51
- end
52
37
  end
53
38
  end
54
39
  end
@@ -17,22 +17,36 @@ module Rensei
17
17
  end
18
18
  end
19
19
 
20
+ refine Array do
21
+ def type
22
+ self[0]
23
+ end
24
+
25
+ def children
26
+ self[1]
27
+ end
28
+ end
29
+
20
30
  refine String do
21
31
  def bracket(prefix = "(", suffix = ")")
22
32
  "#{prefix}#{self}#{suffix}"
23
33
  end
24
34
 
25
35
  def escape
26
- dump[1..-2]
36
+ inspect[1..-2]
27
37
  end
28
38
  end
29
39
  }
30
40
 
31
41
  module Base
32
42
  def unparse(node, opt = {})
33
- return node unless RubyVM::AbstractSyntaxTree::Node === node || Hash === node
34
- method_name = "NODE_#{node.type}"
35
- respond_to?(method_name, true) ? send(method_name, node, opt.dup) : node
43
+ case node
44
+ when RubyVM::AbstractSyntaxTree::Node, Hash, Array
45
+ method_name = "NODE_#{node.type}"
46
+ respond_to?(method_name, true) ? send(method_name, node, opt.dup) : node
47
+ else
48
+ node
49
+ end
36
50
  end
37
51
 
38
52
  private
@@ -45,18 +59,32 @@ module Rensei
45
59
  # format: [nd_head]; ...; [nd_next]
46
60
  # example: foo; bar
47
61
  def NODE_BLOCK(node, opt = {})
48
- node.children.each_slice(2).map { |head, next_|
49
- if head&.type == :BEGIN && opt.delete(:NODE_BEGIN_WITHOUT_BEGIN)
50
- "#{unparse(next_, opt)}"
51
- # Support by BEGIN { foo }
52
- elsif next_&.type == :BEGIN
53
- "BEGIN { #{unparse(head.children.first, opt)} }"
62
+ node.children.then { |head, *nexts|
63
+ if without_BEGIN = opt.fetch(:without_BEGIN, false)
64
+ begin_ = proc { |str, _| str }
65
+ else
66
+ begin_ = proc { |str, semicolon|
67
+ if semicolon
68
+ "begin; #{str}; end"
69
+ else
70
+ "begin #{str}; end"
71
+ end
72
+ }
73
+ end
74
+ opt.merge!(within_BEGIN: !without_BEGIN)
75
+ opt.delete(:without_BEGIN)
76
+ if head.type == :BEGIN && head.children == [nil]
77
+ begin_.(nexts.map(&_unparse(opt)).join("; "), true)
54
78
  elsif head.type == :BEGIN
55
- "begin; #{unparse(next_, opt)}; end"
79
+ "BEGIN { #{unparse(head, opt)} }; #{nexts.drop(1).map(&_unparse(opt)).join("; ")}"
56
80
  else
57
- "#{unparse(head, opt)};#{next_ ? " #{unparse(next_, opt)}" : ""}"
81
+ if nexts.empty?
82
+ "#{unparse(head, opt)};"
83
+ else
84
+ begin_.([head, *nexts].map(&_unparse(opt)).join("; "), false)
85
+ end
58
86
  end
59
- }.join("; ")
87
+ }
60
88
  end
61
89
 
62
90
  # if statement
@@ -65,9 +93,9 @@ module Rensei
65
93
  def NODE_IF(node, opt = {})
66
94
  node.children.then { |cond, body, else_|
67
95
  <<~EOS.chomp
68
- if #{unparse(cond, opt)}
96
+ (if #{unparse(cond, opt)}
69
97
  #{unparse(body, opt)}#{else_ ? "\nelse\n #{unparse(else_, opt)}" : ""}
70
- end
98
+ end)
71
99
  EOS
72
100
  }
73
101
  end
@@ -78,9 +106,9 @@ module Rensei
78
106
  def NODE_UNLESS(node, opt = {})
79
107
  node.children.then { |cond, body, else_|
80
108
  <<~EOS.chomp
81
- unless #{unparse(cond, opt)}
109
+ (unless #{unparse(cond, opt)}
82
110
  #{unparse(body, opt)}#{else_ ? "\nelse\n #{unparse(else_, opt)}" : ""}
83
- end
111
+ end)
84
112
  EOS
85
113
  }
86
114
  end
@@ -117,7 +145,7 @@ module Rensei
117
145
  def NODE_WHEN(node, opt = {})
118
146
  node.children.then { |head, body, next_|
119
147
  <<~EOS.chomp
120
- when #{unparse(head, opt.merge(NODE_ARRAY_EXPAND: true))}
148
+ when #{unparse(head, opt.merge(expand_ARRAY: true))}
121
149
  #{unparse(body, opt)}
122
150
  #{next_&.type == :WHEN || next_.nil? ? unparse(next_, opt) : "else\n #{unparse(next_, opt)}"}
123
151
  EOS
@@ -247,14 +275,22 @@ module Rensei
247
275
  # format: begin; [nd_body]; end
248
276
  # example: begin; 1; end
249
277
  def NODE_BEGIN(node, opt = {})
250
- return "" if node.children.first.nil?
251
- # return "begin; end" if node.children.first.nil?
252
278
  node.children.then { |body|
253
- <<~EOS.chomp
254
- begin
255
- #{unparse(body, opt)}
279
+ if opt.delete(:pattern_match_BEGIN)
280
+ "^(#{body.map(&_unparse(opt)).join("; ")})"
281
+ elsif opt.delete(:without_BEGIN)
282
+ "#{body.map(&_unparse(opt)).join("; ")}"
283
+ elsif opt.delete(:within_BEGIN)
284
+ "begin #{body.map(&_unparse(opt)).join("; ")} end"
285
+ elsif body == [nil]
286
+ ""
287
+ else
288
+ <<~EOS.chomp
289
+ begin
290
+ #{body.map(&_unparse(opt)).join("; ")}
291
+ end
292
+ EOS
256
293
  end
257
- EOS
258
294
  }
259
295
  end
260
296
 
@@ -277,16 +313,16 @@ module Rensei
277
313
  # example: begin; foo; rescue; bar; else; baz; end
278
314
  def NODE_RESBODY(node, opt = {})
279
315
  node.children.then { |args, body|
280
- args_ = args&.then { |it| unparse(it, opt.merge(NODE_ARRAY_EXPAND: true)) + ";" }
316
+ args_ = args&.then { |it| unparse(it, opt.merge(expand_ARRAY: true)) }
281
317
  if body.type == :BLOCK
282
318
  if body.children.first&.children[1]&.type == :ERRINFO
283
- "rescue #{args_}#{unparse(body, opt)}"
319
+ "rescue #{args_} #{unparse(body, opt.merge(without_BEGIN: true))}"
284
320
  else
285
- "rescue #{args_ || ";"}#{unparse(body, opt)}"
321
+ "rescue #{args_}; #{unparse(body, opt)}"
286
322
  end
287
323
  else
288
324
  # MEMO: Support by `begin; foo; rescue; bar; else; baz; end`
289
- "rescue #{args_ || ";"} #{unparse(body, opt)}"
325
+ "rescue #{args_}; #{unparse(body, opt)}"
290
326
  end
291
327
  }
292
328
  end
@@ -320,7 +356,13 @@ module Rensei
320
356
  # example: foo || bar
321
357
  def NODE_OR(node, opt = {})
322
358
  node.children.then { |args|
323
- "(#{args.map { |node| unparse(node, opt) }.join(" || ")})"
359
+ # Support pattern match
360
+ # in String | Integer
361
+ if opt[:pattern_match_OR]
362
+ "#{args.map { |node| unparse(node, opt) }.join(" | ")}"
363
+ else
364
+ "(#{args.map { |node| unparse(node, opt) }.join(" || ")})"
365
+ end
324
366
  }
325
367
  end
326
368
 
@@ -338,12 +380,12 @@ module Rensei
338
380
 
339
381
  # Support: (a,) = value
340
382
  if _right&.empty?
341
- _left = unparse(left, opt.merge(NODE_ARRAY_EXPAND: true)) || "*"
383
+ _left = unparse(left, opt.merge(expand_ARRAY: true, ignore_equal_NODE_ATTRASGN: true)) || "*"
342
384
  elsif left
343
385
  if node_masgn && left.children.count <= 2
344
- _left = left.children.map(&_unparse(opt.merge(NODE_ARRAY_EXPAND: true))).first
386
+ _left = left.children.map(&_unparse(opt.merge(expand_ARRAY: true, ignore_equal_NODE_ATTRASGN: true))).first
345
387
  else
346
- _left = left.children.map(&_unparse(opt.merge(NODE_ARRAY_EXPAND: true))).join(", ")
388
+ _left = left.children.map(&_unparse(opt.merge(expand_ARRAY: true, ignore_equal_NODE_ATTRASGN: true))).join(", ")
347
389
  end
348
390
  end
349
391
 
@@ -373,13 +415,14 @@ module Rensei
373
415
  # example: x = foo
374
416
  def NODE_LASGN(node, opt = {})
375
417
  node.children.then { |vid, value|
418
+ _value = unparse(value, opt)
376
419
  if value == :NODE_SPECIAL_REQUIRED_KEYWORD
377
420
  "#{vid}:"
378
421
  elsif opt.delete(:KW_ARG)
379
422
  "#{vid}:#{value&.then { |it| " #{unparse(it, opt)}" }}"
380
- elsif value.nil? || (_value = unparse(value, opt)).empty?
423
+ elsif value.nil? || (_value).empty?
381
424
  "#{vid}"
382
- elsif opt.delete(:NODE_LASGN_EXPAND)
425
+ elsif opt.delete(:expand_LASGN)
383
426
  "#{vid} = #{_value}"
384
427
  elsif value.type == :ERRINFO
385
428
  "=> #{vid}"
@@ -414,8 +457,10 @@ module Rensei
414
457
  "#{vid}:#{value&.then { |it| " #{unparse(it, opt)}" }}"
415
458
  elsif value.nil?
416
459
  "#{vid}"
417
- elsif opt.delete(:NODE_DASGN_CURR_EXPAND)
460
+ elsif opt.delete(:expand_DASGN_CURR)
418
461
  "#{vid} = #{unparse(value, opt)}"
462
+ elsif value.type == :ERRINFO
463
+ "=> #{vid}"
419
464
  else
420
465
  "(#{vid} = #{unparse(value, opt)})"
421
466
  end
@@ -484,7 +529,7 @@ module Rensei
484
529
  # example: ary[1] += foo
485
530
  def NODE_OP_ASGN1(node, opt = {})
486
531
  node.children.then { |recv, op, head, mid|
487
- "(#{unparse(recv, opt)}[#{unparse(head, opt.merge(NODE_ARRAY_EXPAND: true))}] #{op}= #{unparse(mid, opt.merge(NODE_ARRAY_EXPAND: true))})"
532
+ "(#{unparse(recv, opt)}[#{unparse(head, opt.merge(expand_ARRAY: true))}] #{op}= #{unparse(mid, opt.merge(expand_ARRAY: true))})"
488
533
  }
489
534
  end
490
535
 
@@ -538,7 +583,8 @@ module Rensei
538
583
  # example: obj.foo(1)
539
584
  def NODE_CALL(node, opt = {})
540
585
  node.children.then { |receiver, mid, args|
541
- "#{unparse(receiver, opt)}.#{unparse(mid, opt)}(#{unparse(args, opt.merge(NODE_ARRAY_EXPAND: true))})"
586
+ opt_flags = _expand_in_XXXCALL(args)
587
+ "#{unparse(receiver, opt)}.#{unparse(mid, opt)}(#{unparse(args, opt.merge(_expand_in_XXXCALL(args)))})"
542
588
  }
543
589
  end
544
590
 
@@ -551,21 +597,38 @@ module Rensei
551
597
  if right == nil
552
598
  "(#{op.to_s.delete_suffix("@")}#{unparse(left, opt)})"
553
599
  else
554
- "(#{unparse(left, opt)} #{op} #{unparse(right, opt.merge(NODE_ARRAY_EXPAND: true))})"
600
+ "(#{unparse(left, opt)} #{op} #{unparse(right, opt.merge(expand_ARRAY: true))})"
555
601
  end
556
602
  }
557
603
  end
558
604
 
605
+ def _expand_in_XXXCALL(node)
606
+ case node&.type
607
+ when :ARRAY, :LIST
608
+ opt_flags = { expand_ARRAY: true }
609
+ when :ARGSCAT
610
+ opt_flags = { expand_ARGSCAT: true }
611
+ when :ARGSPUSH
612
+ opt_flags = { expand_ARGSPUSH: true }
613
+ when :BLOCK_PASS
614
+ _expand_in_XXXCALL(node.children.first)
615
+ else
616
+ opt_flags = { expand_ARRAY: true }
617
+ end
618
+ end
619
+
559
620
  # function call
560
621
  # format: [nd_mid]([nd_args])
561
622
  # example: foo(1)
562
623
  def NODE_FCALL(node, opt = {})
563
624
  node.children.then { |mid, args|
625
+ opt_flags = _expand_in_XXXCALL(args)
626
+
564
627
  # Support `self[key]`
565
628
  if mid == :[]
566
- "self[#{unparse(args, opt.merge(NODE_ARRAY_EXPAND: true))}]"
629
+ "self[#{unparse(args, opt.merge(opt_flags))}]"
567
630
  else
568
- "#{unparse(mid, opt)}(#{unparse(args, opt.merge(NODE_ARRAY_EXPAND: true))})"
631
+ "#{unparse(mid, opt)}(#{unparse(args, opt.merge(opt_flags))})"
569
632
  end
570
633
  }
571
634
  end
@@ -582,7 +645,7 @@ module Rensei
582
645
  # example: obj&.foo(1)
583
646
  def NODE_QCALL(node, opt = {})
584
647
  node.children.then { |receiver, mid, args|
585
- "#{unparse(receiver, opt)}&.#{unparse(mid, opt)}(#{unparse(args, opt.merge(NODE_ARRAY_EXPAND: true))})"
648
+ "#{unparse(receiver, opt)}&.#{unparse(mid, opt)}(#{unparse(args, opt.merge(_expand_in_XXXCALL(args)))})"
586
649
  }
587
650
  end
588
651
 
@@ -591,7 +654,7 @@ module Rensei
591
654
  # example: super 1
592
655
  def NODE_SUPER(node, opt = {})
593
656
  node.children.then { |args, |
594
- "super(#{unparse(args, opt.merge(NODE_ARRAY_EXPAND: true))})"
657
+ "super(#{unparse(args, opt.merge(expand_ARRAY: true))})"
595
658
  }
596
659
  end
597
660
 
@@ -607,8 +670,8 @@ module Rensei
607
670
  # example: [1, 2, 3]
608
671
  def NODE_ARRAY(node, opt = {})
609
672
  node.children.then { |*args, _nil|
610
- if opt[:NODE_ARRAY_EXPAND]
611
- "#{args.map(&_unparse(opt.except(:NODE_ARRAY_EXPAND))).join(", ")}"
673
+ if opt[:expand_ARRAY]
674
+ "#{args.map(&_unparse(opt.except(:expand_ARRAY))).join(", ")}"
612
675
  else
613
676
  "[#{args.map(&_unparse(opt)).join(", ")}]"
614
677
  end
@@ -644,11 +707,21 @@ module Rensei
644
707
  elsif head.children.first.nil?
645
708
  "**#{unparse(head.children[1], opt)}"
646
709
  else
647
- "{ #{
648
- (head).children[0..-2].map(&_unparse(opt)).each_slice(2).map { |key, value|
649
- "#{key} => #{value}"
650
- }.join(", ")
651
- } }"
710
+ result = (head).children[0..-2].each_slice(2).map { |key, value|
711
+ if key.nil?
712
+ "**#{unparse(value, opt)}"
713
+ elsif key.type == :LIT && Symbol === key.children.first
714
+ "#{key.children.first}: #{unparse(value, opt)}"
715
+ else
716
+ "#{unparse(key, opt)} => #{unparse(value, opt)}"
717
+ end
718
+ }.join(", ")
719
+
720
+ if opt[:expand_HASH]
721
+ "#{result}"
722
+ else
723
+ "{ #{result} }"
724
+ end
652
725
  end
653
726
  }
654
727
  end
@@ -658,7 +731,7 @@ module Rensei
658
731
  # example: yield 1
659
732
  def NODE_YIELD(node, opt = {})
660
733
  node.children.then { |head,|
661
- "yield(#{unparse(head, opt.merge(NODE_ARRAY_EXPAND: true))})"
734
+ "yield(#{unparse(head, opt.merge(expand_ARRAY: true))})"
662
735
  }
663
736
  end
664
737
 
@@ -666,7 +739,13 @@ module Rensei
666
739
  # format: [nd_vid](lvar)
667
740
  # example: x
668
741
  def NODE_LVAR(node, opt = {})
669
- node.children.first.to_s
742
+ # Support pattern match
743
+ # in ^expr
744
+ if opt[:pattern_match_LVAR]
745
+ "^#{node.children.first}"
746
+ else
747
+ "#{node.children.first}"
748
+ end
670
749
  end
671
750
 
672
751
  # dynamic variable reference
@@ -770,11 +849,10 @@ module Rensei
770
849
  # format: [nd_lit]
771
850
  # example: 'foo'
772
851
  def NODE_STR(node, opt = {})
773
- node.children.first.dump
774
- if opt.delete(:NODE_STR_IGNORE_QUOTE)
852
+ if opt.delete(:ignore_quote_STR)
775
853
  node.children.first.to_s.escape
776
854
  else
777
- node.children.first.dump
855
+ node.children.first.inspect
778
856
  end
779
857
  end
780
858
 
@@ -798,15 +876,15 @@ module Rensei
798
876
  # format: [nd_lit]
799
877
  # example: \"foo#{ bar }baz\"
800
878
  def NODE_DSTR(node, opt = {})
801
- "\"#{_NODE_DSTR_without_quote(node, opt)}\""
879
+ "\"#{without_DSTR_quote(node, opt)}\""
802
880
  end
803
- def _NODE_DSTR_without_quote(node, opt)
881
+ def without_DSTR_quote(node, opt)
804
882
  node.children.then { |prefix, lit, suffix|
805
883
  suffix_ = suffix&.children&.compact&.map { |it|
806
884
  if it.type == :STR
807
- unparse(it, opt.merge(NODE_STR_IGNORE_QUOTE: true))
885
+ unparse(it, opt.merge(ignore_quote_STR: true))
808
886
  else
809
- unparse(it, opt.merge(NODE_STR_IGNORE_QUOTE: false))
887
+ unparse(it, opt.merge(ignore_quote_STR: false))
810
888
  end
811
889
  }&.join
812
890
  "#{prefix&.escape}#{unparse(lit, opt)}#{suffix_}"
@@ -817,7 +895,7 @@ module Rensei
817
895
  # format: [nd_lit]
818
896
  # example: `foo#{ bar }baz`
819
897
  def NODE_DXSTR(node, opt = {})
820
- "`#{_NODE_DSTR_without_quote(node, opt)}`"
898
+ "`#{without_DSTR_quote(node, opt)}`"
821
899
  end
822
900
 
823
901
  # regexp literal with interpolation
@@ -857,10 +935,22 @@ module Rensei
857
935
  # example: foo(*ary, post_arg1, post_arg2)
858
936
  def NODE_ARGSCAT(node, opt = {})
859
937
  node.children.then { |head, body|
860
- if body.type == :ARRAY
861
- "#{unparse(head, opt)}, #{unparse(body, opt)}"
938
+ case head.type
939
+ when :ARRAY, :LIST
940
+ opt_flags = { expand_ARRAY: true, expand_ARGSCAT: true, expand_ARGSPUSH: false }
941
+ when :ARGSCAT
942
+ opt_flags = { expand_ARRAY: true, expand_ARGSCAT: true, expand_ARGSPUSH: false }
943
+ when :ARGSPUSH
944
+ opt_flags = { expand_ARRAY: false, expand_ARGSCAT: false, expand_ARGSPUSH: true }
862
945
  else
863
- "#{unparse(head, opt)}, *#{unparse(body, opt)}"
946
+ opt_flags = {}
947
+ end
948
+
949
+ star = "*" unless %i(ARRAY LIST).include? body.type
950
+ if opt.delete(:expand_ARGSCAT)
951
+ "#{unparse(head, opt.merge(opt_flags))}, #{star}#{unparse(body, opt.merge(expand_ARRAY: true))}"
952
+ else
953
+ "[#{unparse(head, opt.merge(opt_flags))}, #{star}#{unparse(body, opt.merge(expand_ARRAY: true))}]"
864
954
  end
865
955
  }
866
956
  end
@@ -870,7 +960,22 @@ module Rensei
870
960
  # example: foo(*ary, post_arg)
871
961
  def NODE_ARGSPUSH(node, opt = {})
872
962
  node.children.then { |head, body|
873
- "#{unparse(head, opt)}, #{unparse(body, opt)}"
963
+ case head.type
964
+ when :ARRAY, :LIST
965
+ opt_flags = { expand_ARRAY: true, expand_ARGSCAT: true, expand_ARGSPUSH: false }
966
+ when :ARGSCAT
967
+ opt_flags = { expand_ARRAY: false, expand_ARGSCAT: true, expand_ARGSPUSH: false }
968
+ when :ARGSPUSH
969
+ opt_flags = { expand_ARRAY: false, expand_ARGSCAT: false, expand_ARGSPUSH: true }
970
+ else
971
+ opt_flags = {}
972
+ end
973
+
974
+ if opt.delete(:expand_ARGSPUSH)
975
+ "#{unparse(head, opt.merge(opt_flags))}, #{unparse(body , opt)}"
976
+ else
977
+ "[#{unparse(head, opt.merge(opt_flags))}, #{unparse(body , opt)}]"
978
+ end
874
979
  }
875
980
  end
876
981
 
@@ -879,7 +984,7 @@ module Rensei
879
984
  # example: foo(*ary)
880
985
  def NODE_SPLAT(node, opt = {})
881
986
  node.children.then { |head,|
882
- "*#{unparse(head, opt.merge(NODE_ARRAY_EXPAND: false))}"
987
+ "*#{unparse(head, opt.merge(expand_ARRAY: false))}"
883
988
  }
884
989
  end
885
990
 
@@ -954,7 +1059,7 @@ module Rensei
954
1059
  node.children.then { |cpath, super_, body|
955
1060
  <<~EOS.chomp
956
1061
  class #{unparse(cpath, opt)}#{super_&.then { |it| " < #{unparse(it, opt)}" } }
957
- #{unparse(body, opt.merge(NODE_BEGIN_WITHOUT_BEGIN: true))}
1062
+ #{unparse(body, opt.merge(without_BEGIN: true))}
958
1063
  end
959
1064
  EOS
960
1065
  }
@@ -967,7 +1072,7 @@ module Rensei
967
1072
  node.children.then { |cpath, body|
968
1073
  <<~EOS.chomp
969
1074
  module #{unparse(cpath, opt)}
970
- #{unparse(body, opt.merge(NODE_BEGIN_WITHOUT_BEGIN: true))}
1075
+ #{unparse(body, opt.merge(without_BEGIN: true))}
971
1076
  end
972
1077
  EOS
973
1078
  }
@@ -980,7 +1085,7 @@ module Rensei
980
1085
  node.children.then { |recv, body|
981
1086
  <<~EOS.chomp
982
1087
  class << #{unparse(recv, opt)}
983
- #{unparse(body, opt.merge(NODE_BEGIN_WITHOUT_BEGIN: true))}
1088
+ #{unparse(body, opt.merge(without_BEGIN: true))}
984
1089
  end
985
1090
  EOS
986
1091
  }
@@ -1098,11 +1203,13 @@ module Rensei
1098
1203
  # example: struct.field = foo
1099
1204
  def NODE_ATTRASGN(node, opt = {})
1100
1205
  node.children.then { |recv, mid, args|
1101
- if mid == :[]=
1206
+ if opt.delete(:ignore_equal_NODE_ATTRASGN)
1207
+ "#{unparse(recv, opt)}.#{mid.to_s.delete_suffix("=")}"
1208
+ elsif mid == :[]=
1102
1209
  *args_, right, _ = args.children
1103
- "#{unparse(recv, opt)}[#{args_.map(&_unparse(opt.merge(NODE_ARRAY_EXPAND: true))).join(", ")}] = #{unparse(right, opt.merge(NODE_ARRAY_EXPAND: true))}"
1210
+ "#{unparse(recv, opt)}[#{args_.map(&_unparse(opt.merge(expand_ARRAY: true))).join(", ")}] = #{unparse(right, opt.merge(expand_ARRAY: true))}"
1104
1211
  else
1105
- "#{unparse(recv, opt)}.#{mid}#{unparse(args, opt.merge(NODE_ARRAY_EXPAND: true))}"
1212
+ "#{unparse(recv, opt)}.#{mid}(#{unparse(args, opt.merge(expand_ARRAY: true))})"
1106
1213
  end
1107
1214
  }
1108
1215
  end
@@ -1121,7 +1228,7 @@ module Rensei
1121
1228
  # format: def method_name([nd_body=some], [nd_next..])
1122
1229
  # example: def foo(a, b=1, c); end
1123
1230
  def NODE_OPT_ARG(node, opt = {})
1124
- node.children.map(&_unparse(opt.merge(NODE_DASGN_CURR_EXPAND: true, NODE_LASGN_EXPAND: true))).compact.join(", ")
1231
+ node.children.map(&_unparse(opt.merge(expand_DASGN_CURR: true, expand_LASGN: true))).compact.join(", ")
1125
1232
  end
1126
1233
  def unparse_NODE_OPT_ARG(node, opt = {})
1127
1234
  node.children.then { |head, children|
@@ -1146,7 +1253,7 @@ module Rensei
1146
1253
  # example: a, *rest, z = foo
1147
1254
  def NODE_POSTARG(node, opt = {})
1148
1255
  node.children.then { |_1st, _2nd|
1149
- "#{unparse(_1st, opt)}, #{unparse(_2nd, opt.merge(NODE_ARRAY_EXPAND: true))}"
1256
+ "#{unparse(_1st, opt)}, #{unparse(_2nd, opt.merge(expand_ARRAY: true))}"
1150
1257
  }
1151
1258
  end
1152
1259
 
@@ -1155,16 +1262,16 @@ module Rensei
1155
1262
  # example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, &blk); end
1156
1263
  def NODE_ARGS(node, opt_ = {})
1157
1264
  (
1158
- pre_num,
1159
- pre_init,
1265
+ _, # pre_num
1266
+ _, # pre_init
1160
1267
  opt,
1161
- first_post,
1162
- post_num,
1163
- post_init,
1164
- rest,
1165
- kw,
1166
- kwrest,
1167
- block
1268
+ _, # first_post
1269
+ _, # post_num
1270
+ _, # post_init
1271
+ _, # rest
1272
+ _, # kw
1273
+ _, # kwrest
1274
+ _, # block
1168
1275
  ) = node.children
1169
1276
  "#{unparse(opt, opt_)}#{unparse(kw, opt_)}"
1170
1277
  end
@@ -1188,7 +1295,7 @@ module Rensei
1188
1295
  unparsed_post_init: info[:post_init]&.then { |node|
1189
1296
  node.type == :BLOCK ? node.children.map(&_unparse(opt)) : [unparse(node, opt)]
1190
1297
  } || [],
1191
- unparsed_opt: info[:opt]&.then { |it| unparse_NODE_OPT_ARG(it, opt.merge(NODE_DASGN_CURR_EXPAND: true, NODE_LASGN_EXPAND: true)) } || [],
1298
+ unparsed_opt: info[:opt]&.then { |it| unparse_NODE_OPT_ARG(it, opt.merge(expand_DASGN_CURR: true, expand_LASGN: true)) } || [],
1192
1299
  unparsed_rest: unparse(info[:rest], opt)&.then { |it|
1193
1300
  if it == :NODE_SPECIAL_EXCESSIVE_COMMA
1194
1301
  [" "]
@@ -1196,7 +1303,7 @@ module Rensei
1196
1303
  ["*#{it}"]
1197
1304
  end
1198
1305
  } || [],
1199
- unparsed_kw: info[:kw]&.then { |it| unparse_NODE_KW_ARG(it, opt.merge(NODE_DASGN_CURR_EXPAND: true, NODE_LASGN_EXPAND: true, KW_ARG: true)) } || [],
1306
+ unparsed_kw: info[:kw]&.then { |it| unparse_NODE_KW_ARG(it, opt.merge(expand_DASGN_CURR: true, expand_LASGN: true, KW_ARG: true)) } || [],
1200
1307
  unparsed_kwrest: info[:kwrest]&.then { |it| "**#{unparse(it, opt)}" },
1201
1308
  )
1202
1309
  }
@@ -1218,52 +1325,56 @@ module Rensei
1218
1325
  node.children.then { |tbl, args, body|
1219
1326
  break { args: "", body: unparse(body, opt) } if args.nil?
1220
1327
 
1221
- # info = unparse_NODE_ARGS(args, opt)
1222
1328
  info = unparse_NODE_ARGS(args, opt.merge(_NODE_MASGN: true))
1223
1329
 
1224
1330
  # Support proc { |**| }
1225
1331
  break { args: "**", body: unparse(body, opt) } if tbl == [nil] && info[:kwrest]
1226
1332
 
1333
+ tbl_ = tbl.dup
1227
1334
  pre_args = []
1228
1335
  [info[:pre_num], info[:unparsed_pre_init]&.size || 0].max.times {
1229
- tbl.shift.then { |it|
1336
+ tbl_.shift.then { |it|
1230
1337
  pre_args << (it ? it : info[:unparsed_pre_init].shift)
1231
1338
  }
1232
1339
  }
1233
1340
 
1234
1341
  # skip to opt args
1235
1342
  # e.g. a = 1, b = 2
1236
- tbl = tbl.drop(info[:unparsed_opt].count)
1343
+ tbl_ = tbl_.drop(info[:unparsed_opt].count)
1237
1344
 
1238
1345
  # skip to rest args
1239
1346
  # e.g. *a
1240
- tbl = tbl.drop(info[:unparsed_rest].count)
1347
+ tbl_ = tbl_.drop(info[:unparsed_rest].count)
1241
1348
 
1242
1349
  star = nil
1243
- tbl.take_while(&:nil?).tap { |nils|
1350
+ tbl_.take_while(&:nil?).tap { |nils|
1244
1351
  if info[:unparsed_post_init].count < nils.count
1245
1352
  star = "*"
1246
- tbl = tbl.drop(1)
1353
+ tbl_ = tbl_.drop(1)
1247
1354
  end
1248
1355
  }
1249
1356
 
1250
1357
  post_args = []
1251
1358
  [info[:post_num], info[:unparsed_post_init]&.size || 0].max.times {
1252
- tbl.shift.then { |it|
1359
+ tbl_.shift.then { |it|
1253
1360
  post_args << (it ? it : info[:unparsed_post_init].shift)
1254
1361
  }
1255
1362
  }
1256
1363
 
1257
1364
  # skip to kw args
1258
1365
  # e.g. a:, b: c: 1
1259
- tbl = tbl.drop(info[:unparsed_kw].count.tap { |count| break count + 1 if count != 0 })
1366
+ tbl_ = tbl_.drop(info[:unparsed_kw].count.tap { |count| break count + 1 if count != 0 })
1260
1367
 
1261
- if info[:unparsed_kwrest] == "**" && tbl.fetch(0, 1) != nil
1368
+ if info[:unparsed_kwrest] == "**" && tbl_.fetch(0, 1) != nil
1262
1369
  kwrest = ""
1263
1370
  else
1264
1371
  kwrest = info[:unparsed_kwrest]
1265
1372
  end
1266
1373
 
1374
+ if opt.delete(:ignore_numbered_paramters)
1375
+ pre_args -= [:_1, :_2, :_3, :_4, :_5, :_6, :_7, :_8, :_9]
1376
+ end
1377
+
1267
1378
  params = [
1268
1379
  pre_args,
1269
1380
  info[:unparsed_opt].join(", "),
@@ -1302,9 +1413,13 @@ module Rensei
1302
1413
  # format: case [nd_head]; [nd_body]; end
1303
1414
  # example: case x; in 1; foo; in 2; bar; else baz; end
1304
1415
  def NODE_CASE3(node, opt = {})
1305
- # Ruby 2.7
1306
- # :TODO:
1307
- node
1416
+ node.children.then { |head, body, else_|
1417
+ <<~EOS.chomp
1418
+ case #{unparse(head, opt)}
1419
+ #{unparse(body, opt)}#{else_ ? "\nelse\n#{unparse(else_, opt)}" : ""}
1420
+ end
1421
+ EOS
1422
+ }
1308
1423
  end
1309
1424
 
1310
1425
  # list constructor
@@ -1319,18 +1434,28 @@ module Rensei
1319
1434
  end
1320
1435
 
1321
1436
  def NODE_IN(node, opt = {})
1322
- # TODO
1323
- end
1324
-
1325
- # splat argument following arguments
1326
- # format: ..(*[nd_head], [nd_body..])
1327
- # example: foo(*ary, post_arg1, post_arg2)
1328
- def NODE_ARGSCAT(node, opt = {})
1329
- node.children.then { |head, body|
1330
- if body.type == :LIST
1331
- "#{unparse(head, opt)}, #{unparse(body, opt)}"
1437
+ node.children.then { |head, body, next_|
1438
+ in_ = opt.delete(:without_in) ? "" : "in "
1439
+ next__ = next_&.type == :IN || next_.nil? ? unparse(next_, opt) : "else\n #{unparse(next_, opt)}"
1440
+ case head.type
1441
+ when :IF
1442
+ <<~EOS.chomp
1443
+ #{in_}#{unparse(head.children[1], opt.merge(expand_ARRAY: true))} if #{unparse(head.children[0], opt)}
1444
+ #{unparse(body, opt)}
1445
+ #{next__}
1446
+ EOS
1447
+ when :UNLESS
1448
+ <<~EOS.chomp
1449
+ #{in_}#{unparse(head.children[1], opt.merge(expand_ARRAY: true))} unless #{unparse(head.children[0], opt)}
1450
+ #{unparse(body, opt)}
1451
+ #{next__}
1452
+ EOS
1332
1453
  else
1333
- "#{unparse(head, opt)}, *#{unparse(body, opt)}"
1454
+ <<~EOS.chomp
1455
+ #{in_}#{unparse(head, opt.merge(expand_ARRAY: true))}
1456
+ #{unparse(body, opt)}
1457
+ #{next__}
1458
+ EOS
1334
1459
  end
1335
1460
  }
1336
1461
  end
@@ -1338,19 +1463,52 @@ module Rensei
1338
1463
  # array pattern
1339
1464
  # format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)
1340
1465
  def NODE_ARYPTN(node, opt = {})
1341
- # :TODO:
1342
- node
1466
+ node.children.then { |pconst, pre, rest, post|
1467
+ # e.g. in Array[a, b]
1468
+ pconst_ = unparse(pconst, opt) if pconst
1469
+
1470
+ opt_flags = { expand_ARRAY: true, expand_HASH: true, pattern_match_OR: true, pattern_match_LVAR: true, pattern_match_BEGIN: true }
1471
+ pre_ = unparse(pre, opt.merge(opt_flags))
1472
+ if rest == :NODE_SPECIAL_NO_NAME_REST
1473
+ rest_ = "*"
1474
+ elsif rest
1475
+ rest_ = "*#{unparse(rest, opt.merge(opt_flags))}"
1476
+ end
1477
+ post_ = unparse(post, opt.merge(opt_flags))
1478
+ "#{pconst_}[#{[pre_, rest_, post_].compact.join(", ")}]"
1479
+ }
1343
1480
  end
1344
1481
 
1482
+ # hash pattern
1483
+ # format: [nd_pconst]([nd_pkwargs], ..., **[nd_pkwrestarg])
1345
1484
  def NODE_HSHPTN(node, opt = {})
1346
- # :TODO:
1347
- node
1485
+ node.children.then { |pconst, pkwargs, pkwrestarg|
1486
+
1487
+ opt_flags = { expand_ARRAY: true, expand_HASH: true, pattern_match_OR: true, pattern_match_LVAR: true, pattern_match_BEGIN: true }
1488
+
1489
+ pkwargs_ = unparse(pkwargs, opt.merge(opt_flags))
1490
+
1491
+ if pkwrestarg == :NODE_SPECIAL_NO_REST_KEYWORD
1492
+ pkwargs_ += ", **nil"
1493
+ elsif pkwrestarg
1494
+ pkwargs_ += ", **#{unparse(pkwrestarg, opt.merge(opt_flags))}"
1495
+ end
1496
+
1497
+ # Support `in A[a: 1, b: 2]`
1498
+ if pconst
1499
+ "#{unparse(pconst, opt)}[#{pkwargs_}]"
1500
+ else
1501
+ "{ #{pkwargs_} }"
1502
+ end
1503
+ }
1348
1504
  end
1349
1505
  end
1350
1506
 
1351
- module Ruby3_0_0
1507
+ module Ruby2_7_2
1352
1508
  include Ruby2_7_0
1353
1509
 
1510
+ private
1511
+
1354
1512
  # attr assignment with operator
1355
1513
  # format: [nd_recv].[attr] [nd_next->nd_mid]= [nd_value]
1356
1514
  # where [attr]: [nd_next->nd_vid]
@@ -1360,6 +1518,17 @@ module Rensei
1360
1518
  "#{unparse(recv, opt)}.#{attr} #{op}= #{unparse(mid, opt)}"
1361
1519
  }
1362
1520
  end
1521
+ end
1522
+
1523
+ module Ruby3_0_0
1524
+ include Ruby2_7_2
1525
+
1526
+ # method call with block
1527
+ # format: [nd_iter] { [nd_body] }
1528
+ # example: 3.times { foo }
1529
+ def NODE_ITER(node, opt = {})
1530
+ super(node, opt.merge(ignore_numbered_paramters: true))
1531
+ end
1363
1532
 
1364
1533
  # string literal with interpolation
1365
1534
  # format: [nd_lit]
@@ -1374,15 +1543,94 @@ module Rensei
1374
1543
  end
1375
1544
  }
1376
1545
  end
1546
+
1547
+ # case statement (pattern matching)
1548
+ # format: case [nd_head]; [nd_body]; end
1549
+ # example: case x; in 1; foo; in 2; bar; else baz; end
1550
+ def NODE_CASE3(node, opt = {})
1551
+ node.children.then { |head, body, else_|
1552
+ # Add super `42 => result`
1553
+ if body.children[1].nil?
1554
+ "#{unparse(head, opt)} => #{unparse(body, opt.merge(without_in: true))}"
1555
+ else
1556
+ super
1557
+ end
1558
+ }
1559
+ end
1560
+
1561
+ # find pattern
1562
+ # format: [nd_pconst](*[pre_rest_arg], args, ..., *[post_rest_arg])
1563
+ def NODE_FNDPTN(node, opt = {})
1564
+ node.children.then { |pconst, pre, rest, post|
1565
+ # e.g. in Array[a, b]
1566
+ pconst_ = unparse(pconst, opt) if pconst
1567
+
1568
+ opt_flags = { expand_ARRAY: true, expand_HASH: true, pattern_match_OR: true, pattern_match_LVAR: true }
1569
+
1570
+ if pre == :NODE_SPECIAL_NO_NAME_REST
1571
+ pre_ = "*"
1572
+ elsif pre
1573
+ pre_ = "*#{unparse(pre, opt.merge(opt_flags))}"
1574
+ end
1575
+
1576
+ rest_ = unparse(rest, opt.merge(opt_flags))
1577
+
1578
+ if post == :NODE_SPECIAL_NO_NAME_REST
1579
+ post_ = "*"
1580
+ elsif post
1581
+ post_ = "*#{unparse(post, opt.merge(opt_flags))}"
1582
+ end
1583
+
1584
+ "#{pconst_}[#{[pre_, rest_, post_].compact.join(", ")}]"
1585
+ }
1586
+ end
1587
+
1588
+ # method definition
1589
+ # format: def [nd_mid] [nd_defn]; end
1590
+ # example: def foo; bar; end
1591
+ def NODE_DEFN(node, opt = {})
1592
+ node.children.then { |mid, defn|
1593
+ # Add support `def hoge = 42`
1594
+ if defn.children[1].nil?
1595
+ info = unparse_NODE_SCOPE(defn, opt)
1596
+ "def #{mid} = #{info[:body]}"
1597
+ else
1598
+ super
1599
+ end
1600
+ }
1601
+ end
1602
+
1603
+ # singleton method definition
1604
+ # format: def [nd_recv].[nd_mid] [nd_defn]; end
1605
+ # example: def obj.foo; bar; end
1606
+ def NODE_DEFS(node, opt = {})
1607
+ node.children.then { |recv, mid, defn|
1608
+ # Add support `def obj.hoge = 42`
1609
+ if defn.children[1].nil?
1610
+ info = unparse_NODE_SCOPE(defn, opt)
1611
+ "def #{unparse(recv, opt)}.#{mid} = #{info[:body]}"
1612
+ else
1613
+ super
1614
+ end
1615
+ }
1616
+ end
1617
+ end
1618
+
1619
+ module Ruby3_1_0
1620
+ include Ruby3_0_0
1377
1621
  end
1378
1622
 
1379
1623
  case RUBY_VERSION
1380
1624
  when ("2.6.0"..."2.7.0")
1381
1625
  VERSION = Ruby2_6_0
1382
- when ("2.7.0"..."3.0.0")
1626
+ when ("2.7.0"..."2.7.2")
1383
1627
  VERSION = Ruby2_7_0
1384
- when ("3.0.0"...)
1628
+ when ("2.7.2"..."3.0.0")
1629
+ VERSION = Ruby2_7_2
1630
+ when ("3.0.0"..."3.1.0")
1385
1631
  VERSION = Ruby3_0_0
1632
+ when ("3.1.0"...)
1633
+ VERSION = Ruby3_1_0
1386
1634
  else
1387
1635
  railse "Not implemented Ruby version #{RUBY_VERSION}"
1388
1636
  end
@@ -1391,8 +1639,8 @@ module Rensei
1391
1639
  include VERSION
1392
1640
  end
1393
1641
 
1394
- def self.unparse(node)
1395
- Caller.new.unparse(node)
1642
+ def self.unparse(node, opt = {})
1643
+ Caller.new.unparse(node, opt)
1396
1644
  end
1397
1645
  end
1398
1646
  end
@@ -1,3 +1,3 @@
1
1
  module Rensei
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
data/rake_spec_all.sh ADDED
@@ -0,0 +1,6 @@
1
+ #!/bin/bash -ex
2
+ RBENV_VERSION=2.6.4 bundle exec rake spec
3
+ RBENV_VERSION=2.7.0 bundle exec rake spec
4
+ RBENV_VERSION=2.7.2 bundle exec rake spec
5
+ RBENV_VERSION=3.0.1 bundle exec rake spec
6
+ RBENV_VERSION=3.1.0-dev bundle exec rake spec
data/rensei.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.description = %q{Unparse from `RubyVM::AbstractSyntaxTree::Node` to Ruby code.}
11
11
  spec.homepage = ""
12
12
  spec.license = "MIT"
13
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.6.4")
14
14
 
15
15
  # Specify which files should be added to the gem when it is released.
16
16
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -20,4 +20,6 @@ Gem::Specification.new do |spec|
20
20
  spec.bindir = "exe"
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "super_diff"
23
25
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rensei
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - manga_osyo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-30 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-08-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: super_diff
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description: Unparse from `RubyVM::AbstractSyntaxTree::Node` to Ruby code.
14
28
  email:
15
29
  - manga.osyo@gmail.com
@@ -17,6 +31,7 @@ executables: []
17
31
  extensions: []
18
32
  extra_rdoc_files: []
19
33
  files:
34
+ - ".github/workflows/rensei.yml"
20
35
  - ".gitignore"
21
36
  - ".rspec"
22
37
  - ".travis.yml"
@@ -26,10 +41,12 @@ files:
26
41
  - Rakefile
27
42
  - bin/console
28
43
  - bin/setup
44
+ - bundle_install_all.sh
29
45
  - lib/rensei.rb
30
46
  - lib/rensei/node_to_hash.rb
31
47
  - lib/rensei/unparser.rb
32
48
  - lib/rensei/version.rb
49
+ - rake_spec_all.sh
33
50
  - rensei.gemspec
34
51
  - sample/bocchi.rb
35
52
  - sample/sample.rb
@@ -45,14 +62,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
45
62
  requirements:
46
63
  - - ">="
47
64
  - !ruby/object:Gem::Version
48
- version: 2.3.0
65
+ version: 2.6.4
49
66
  required_rubygems_version: !ruby/object:Gem::Requirement
50
67
  requirements:
51
68
  - - ">="
52
69
  - !ruby/object:Gem::Version
53
70
  version: '0'
54
71
  requirements: []
55
- rubygems_version: 3.1.4
72
+ rubygems_version: 3.1.6
56
73
  signing_key:
57
74
  specification_version: 4
58
75
  summary: Unparse from `RubyVM::AbstractSyntaxTree::Node` to Ruby code.