ruby-next-core 0.10.0 → 0.10.5

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: 6cab7345f16f61d3a35a307024885c4b9a0055bb946f473bdd5a386b27175ec2
4
- data.tar.gz: c3b2004bf5cd1b9dd49d2a7892bd3e88472a632f4cdc8da310bdb56fb96171d9
3
+ metadata.gz: 34691e69e3f0725ece379addac8297e0b69e9ed0a55fb1a06bfe3ca970213eae
4
+ data.tar.gz: 23edfba446641d2658d754f3678eb79de8ee332a4d481d4714887769392ad272
5
5
  SHA512:
6
- metadata.gz: 4f6b3d6f64e0303e1b69fa5a99ececcf605c7413285c05feb03d9308da8449296fbea96b8779a3ac6b72dca8351ac10cd20f11161b1581ac6a60a85d951ca0d3
7
- data.tar.gz: 44e5f05020cae47e13d1a89627c94d890b07daccd1e7dcf51e2e4e0eed208fca2c946e4db674f53fa0581477a368e80c73474ffc657a53f55c1e962bd3d668ba
6
+ metadata.gz: 0d41912b15fd77ed3a1d2d2665a3375a212a1815e26e85724d2e0960af1daa5c714b126efca1c5621dc76b16af3d612c35a077be3472ca607548a757dea253ac
7
+ data.tar.gz: 02d860b6d0730f48b990c6c8dd9a3ef49e022ea7a0ae637a64cd0c29a74ee1e6c2b0f4cdf0ed25886029a49d9e2df8044b9e016aead9733ca322fd3579093949
@@ -2,6 +2,28 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.10.5 (2020-10-13)
6
+
7
+ - Fix Unparser 0.5.0 compatibility. ([@palkan][])
8
+
9
+ ## 0.10.4 (2020-10-09)
10
+
11
+ - Restrict Unparser dependency. ([@palkan][])
12
+
13
+ Unparser 0.5.0 is currently not supported.
14
+
15
+ ## 0.10.3 (2020-09-28)
16
+
17
+ - Update RuboCop integration to handle the latest Parser changes. ([@palkan][])
18
+
19
+ Parser 2.7.1.5 unified endless and normal methods and rightward and leftward assignments, thus, making some cops report false negatives.
20
+
21
+ ## 0.10.2 (2020-09-09)
22
+
23
+ - Fix regression when `nextify` produces incorrect files for 2.7. ([@palkan][])
24
+
25
+ ## ~~0.10.1~~
26
+
5
27
  ## 0.10.0 (2020-09-02)
6
28
 
7
29
  - Add proposed shorthand Hash syntax. ([@palkan][])
data/README.md CHANGED
@@ -35,6 +35,7 @@ Read more about the motivation behind the Ruby Next in this post: [Ruby Next: Ma
35
35
  ## Examples
36
36
 
37
37
  - Ruby gems
38
+ - [action_policy](https://github.com/palkan/action_policy)
38
39
  - [anyway_config](https://github.com/palkan/anyway_config)
39
40
  - [graphql-fragment_cache](https://github.com/DmitryTsepelev/graphql-ruby-fragment_cache)
40
41
  - Rails applications
@@ -475,6 +476,8 @@ RUBY_NEXT_CORE_STRATEGY=backports ruby-next nextify lib/
475
476
 
476
477
  **NOTE:** For Ruby 2.2, safe navigation operator (`&.`) and squiggly heredocs (`<<~TXT`) support is provided.
477
478
 
479
+ **IMPORTANT:** Unparser `~> 0.4.8` is required to run the transpiler on Ruby <2.4.
480
+
478
481
  ## Proposed and edge features
479
482
 
480
483
  Ruby Next aims to bring edge and proposed features to Ruby community before they (hopefully) reach an official Ruby release.
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path("../../lib", __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ $VERBOSE = nil
6
+
7
+ require "bundler/setup"
8
+
9
+ require "ruby-next/language"
10
+
11
+ contents =
12
+ if File.exist?(ARGV[0])
13
+ File.read(ARGV[0])
14
+ else
15
+ ARGV[0]
16
+ end
17
+
18
+ ast = RubyNext::Language.parse(contents)
19
+ puts Unparser.unparse(ast)
@@ -5,6 +5,13 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  require "bundler/setup"
7
7
 
8
+ require "optparse"
9
+
10
+ begin
11
+ require "pry-byebug"
12
+ rescue LoadError
13
+ end
14
+
8
15
  ENV["RUBY_NEXT_EDGE"] = "1"
9
16
  ENV["RUBY_NEXT_PROPOSED"] = "1"
10
17
 
@@ -13,16 +20,23 @@ require "ruby-next/language/rewriters/runtime"
13
20
 
14
21
  contents =
15
22
  if File.exist?(ARGV[0])
16
- File.read(ARGV[0])
23
+ File.read(ARGV.shift)
17
24
  else
18
- ARGV[0]
25
+ ARGV.shift
19
26
  end
20
27
 
21
- opts =
22
- if ARGV[1] && ARGV[1] == "--current"
23
- {rewriters: RubyNext::Language.current_rewriters}
24
- else
25
- {}
28
+ transform_opts = {}
29
+
30
+ OptionParser.new do |opts|
31
+ opts.banner = "Usage: transform filepath_or_code [options]"
32
+
33
+ opts.on("--current", "Use rewriters for the current Ruby version only") do
34
+ transform_opts[:rewriters] = RubyNext::Language.current_rewriters
35
+ end
36
+
37
+ opts.on("--rewrite", "User rewrite transpiling mode") do
38
+ RubyNext::Language.mode = :rewrite
26
39
  end
40
+ end.parse!
27
41
 
28
- puts RubyNext::Language.transform(contents, **opts)
42
+ puts RubyNext::Language.transform(contents, **transform_opts)
@@ -95,7 +95,7 @@ module RubyNext
95
95
  exit 0
96
96
  end
97
97
 
98
- unless ((!lib_path.nil?) || nil) && lib_path.then(&File.method(:exist?))
98
+ unless ((!lib_path.nil? || nil) && lib_path.then(&File.method(:exist?)))
99
99
  $stdout.puts "Path not found: #{lib_path}"
100
100
  $stdout.puts optparser.help
101
101
  exit 2
@@ -148,6 +148,9 @@ module RubyNext
148
148
 
149
149
  # Then, generate the source code for the next version
150
150
  transpile path, contents, version: version
151
+ rescue SyntaxError, StandardError => e
152
+ warn "Failed to transpile #{path}: #{e.class} — #{e.message}"
153
+ exit 1
151
154
  end
152
155
 
153
156
  def save(contents, path, version)
@@ -8,7 +8,7 @@ module RubyNext
8
8
  def eval(source, bind = nil, *args)
9
9
  new_source = ::RubyNext::Language::Runtime.transform(
10
10
  source,
11
- using: ((!bind.nil?) || nil) && bind.receiver == TOPLEVEL_BINDING.receiver || ((!(((!bind.nil?) || nil) && bind.receiver).nil?) || nil) && (((!bind.nil?) || nil) && bind.receiver).is_a?(Module)
11
+ using: ((!bind.nil? || nil) && bind.receiver) == TOPLEVEL_BINDING.receiver || ((!((!bind.nil? || nil) && bind.receiver).nil? || nil) && ((!bind.nil? || nil) && bind.receiver).is_a?(Module))
12
12
  )
13
13
  RubyNext.debug_source(new_source, "(#{caller_locations(1, 1).first})")
14
14
  super new_source, bind, *args
@@ -94,24 +94,25 @@ module RubyNext
94
94
  private
95
95
 
96
96
  def replace(range, ast)
97
- ((!@source_rewriter.nil?) || nil) && @source_rewriter.replace(range, unparse(ast))
97
+ ((!@source_rewriter.nil? || nil) && @source_rewriter.replace(range, unparse(ast)))
98
98
  end
99
99
 
100
100
  def remove(range)
101
- ((!@source_rewriter.nil?) || nil) && @source_rewriter.remove(range)
101
+ ((!@source_rewriter.nil? || nil) && @source_rewriter.remove(range))
102
102
  end
103
103
 
104
104
  def insert_after(range, ast)
105
- ((!@source_rewriter.nil?) || nil) && @source_rewriter.insert_after(range, unparse(ast))
105
+ ((!@source_rewriter.nil? || nil) && @source_rewriter.insert_after(range, unparse(ast)))
106
106
  end
107
107
 
108
108
  def insert_before(range, ast)
109
- ((!@source_rewriter.nil?) || nil) && @source_rewriter.insert_before(range, unparse(ast))
109
+ ((!@source_rewriter.nil? || nil) && @source_rewriter.insert_before(range, unparse(ast)))
110
110
  end
111
111
 
112
112
  def unparse(ast)
113
113
  return ast if ast.is_a?(String)
114
- Unparser.unparse(ast)
114
+
115
+ Unparser.unparse(ast).chomp
115
116
  end
116
117
 
117
118
  attr_reader :context
@@ -55,7 +55,7 @@ module RubyNext
55
55
  attr_reader :current_index
56
56
 
57
57
  def index_arg?(node)
58
- ((!(((!current_index.nil?) || nil) && current_index.children).nil?) || nil) && (((!current_index.nil?) || nil) && current_index.children).include?(node)
58
+ ((!((!current_index.nil? || nil) && current_index.children).nil? || nil) && ((!current_index.nil? || nil) && current_index.children).include?(node))
59
59
  end
60
60
  end
61
61
  end
@@ -244,7 +244,7 @@ module RubyNext
244
244
  @predicates = Predicates::CaseIn.new
245
245
 
246
246
  matchee_ast =
247
- s(:lvasgn, MATCHEE, node.children[0])
247
+ s(:begin, s(:lvasgn, MATCHEE, node.children[0]))
248
248
 
249
249
  patterns = locals.with(
250
250
  matchee: MATCHEE,
@@ -273,7 +273,7 @@ module RubyNext
273
273
  @predicates = Predicates::Noop.new
274
274
 
275
275
  matchee =
276
- s(:lvasgn, MATCHEE, node.children[0])
276
+ s(:begin, s(:lvasgn, MATCHEE, node.children[0]))
277
277
 
278
278
  pattern =
279
279
  locals.with(
@@ -285,9 +285,10 @@ module RubyNext
285
285
  :"#{node.children[1].type}_clause",
286
286
  node.children[1]
287
287
  ).then do |node|
288
- s(:or,
289
- node,
290
- no_matching_pattern)
288
+ s(:begin,
289
+ s(:or,
290
+ node,
291
+ no_matching_pattern))
291
292
  end
292
293
  end
293
294
 
@@ -309,7 +310,7 @@ module RubyNext
309
310
  remove(node.children[0].loc.expression)
310
311
 
311
312
  node.children[1..-1].each.with_index do |clause, i|
312
- if ((!clause.nil?) || nil) && clause.type == :in_pattern
313
+ if ((!clause.nil? || nil) && clause.type) == :in_pattern
313
314
  # handle multiline clauses differently
314
315
  if clause.loc.last_line > clause.children[0].loc.last_line + 1
315
316
  height = clause.loc.last_line - clause.children[0].loc.last_line
@@ -340,7 +341,7 @@ module RubyNext
340
341
  clauses = []
341
342
 
342
343
  nodes.each do |clause|
343
- if ((!clause.nil?) || nil) && clause.type == :in_pattern
344
+ if ((!clause.nil? || nil) && clause.type) == :in_pattern
344
345
  clauses << build_when_clause(clause)
345
346
  else
346
347
  else_clause = process(clause)
@@ -378,9 +379,10 @@ module RubyNext
378
379
  predicates.const(case_eq_clause(const, right), const).then do |node|
379
380
  next node if pattern.nil?
380
381
 
381
- s(:and,
382
- node,
383
- send(:"#{pattern.type}_clause", pattern))
382
+ s(:begin,
383
+ s(:and,
384
+ node,
385
+ send(:"#{pattern.type}_clause", pattern)))
384
386
  end
385
387
  end
386
388
 
@@ -391,13 +393,14 @@ module RubyNext
391
393
  send :"#{child.type}_clause", child
392
394
  end
393
395
  end
394
- s(:or, *children)
396
+ s(:begin, s(:or, *children))
395
397
  end
396
398
 
397
399
  def match_as_clause(node, right = s(:lvar, locals[:matchee]))
398
- s(:and,
399
- send(:"#{node.children[0].type}_clause", node.children[0], right),
400
- match_var_clause(node.children[1], right))
400
+ s(:begin,
401
+ s(:and,
402
+ send(:"#{node.children[0].type}_clause", node.children[0], right),
403
+ match_var_clause(node.children[1], right)))
401
404
  end
402
405
 
403
406
  def match_var_clause(node, left = s(:lvar, locals[:matchee]))
@@ -405,9 +408,10 @@ module RubyNext
405
408
 
406
409
  check_match_var_alternation! node.children[0]
407
410
 
408
- s(:or,
409
- s(:lvasgn, node.children[0], left),
410
- s(:true))
411
+ s(:begin,
412
+ s(:or,
413
+ s(:begin, s(:lvasgn, node.children[0], left)),
414
+ s(:true)))
411
415
  end
412
416
 
413
417
  def pin_clause(node, right = s(:lvar, locals[:matchee]))
@@ -417,8 +421,8 @@ module RubyNext
417
421
 
418
422
  def case_eq_clause(node, right = s(:lvar, locals[:matchee]))
419
423
  predicates.terminate!
420
- s(:send,
421
- process(node), :===, right)
424
+ s(:begin, s(:send,
425
+ process(node), :===, right))
422
426
  end
423
427
 
424
428
  #=========== ARRAY PATTERN (START) ===============
@@ -429,10 +433,11 @@ module RubyNext
429
433
  # if there is no rest or tail, match the size first
430
434
  unless node.type == :array_pattern_with_tail || node.children.any? { |n| n.type == :match_rest }
431
435
  size_check = predicates.array_size(
432
- s(:send,
433
- node.children.size.to_ast_node,
434
- :==,
435
- s(:send, s(:lvar, locals[:arr]), :size)),
436
+ s(:begin,
437
+ s(:send,
438
+ node.children.size.to_ast_node,
439
+ :==,
440
+ s(:send, s(:lvar, locals[:arr]), :size))),
436
441
  node.children.size
437
442
  )
438
443
  end
@@ -448,9 +453,10 @@ module RubyNext
448
453
 
449
454
  right = s(:and, size_check, right) if size_check
450
455
 
451
- s(:and,
452
- dnode,
453
- right)
456
+ s(:begin,
457
+ s(:and,
458
+ dnode,
459
+ right))
454
460
  end
455
461
  end
456
462
 
@@ -468,14 +474,17 @@ module RubyNext
468
474
  predicates.array_deconstructed(
469
475
  s(:and,
470
476
  respond_check,
471
- s(:and,
472
- s(:or,
473
- s(:lvasgn, locals[:arr], right),
474
- s(:true)),
475
- s(:or,
476
- s(:send,
477
- s(:const, nil, :Array), :===, s(:lvar, locals[:arr])),
478
- raise_error(:TypeError, "#deconstruct must return Array"))))
477
+ s(:begin,
478
+ s(:and,
479
+ s(:begin,
480
+ s(:or,
481
+ s(:begin, s(:lvasgn, locals[:arr], right)),
482
+ s(:true))),
483
+ s(:begin,
484
+ s(:or,
485
+ s(:send,
486
+ s(:const, nil, :Array), :===, s(:lvar, locals[:arr])),
487
+ raise_error(:TypeError, "#deconstruct must return Array"))))))
479
488
  )
480
489
  end
481
490
 
@@ -485,9 +494,10 @@ module RubyNext
485
494
  send("#{head.type}_array_element", head, index).then do |node|
486
495
  next node if tail.empty?
487
496
 
488
- s(:and,
489
- node,
490
- array_element(index + 1, *tail))
497
+ s(:begin,
498
+ s(:and,
499
+ node,
500
+ array_element(index + 1, *tail)))
491
501
  end
492
502
  end
493
503
 
@@ -526,15 +536,17 @@ module RubyNext
526
536
 
527
537
  pattern = array_rest_element(*nodes, index).then do |needle|
528
538
  next needle unless head_match
529
- s(:and,
530
- needle,
531
- head_match)
539
+ s(:begin,
540
+ s(:and,
541
+ needle,
542
+ head_match))
532
543
  end.then do |headed_needle|
533
544
  next headed_needle unless tail_match
534
545
 
535
- s(:and,
536
- headed_needle,
537
- tail_match)
546
+ s(:begin,
547
+ s(:and,
548
+ headed_needle,
549
+ tail_match))
538
550
  end
539
551
 
540
552
  s(:block,
@@ -550,13 +562,14 @@ module RubyNext
550
562
  next block if match_vars.empty?
551
563
 
552
564
  # We need to declare match vars outside of `find` block
553
- locals_declare = s(:masgn,
565
+ locals_declare = s(:begin, s(:masgn,
554
566
  s(:mlhs, *match_vars),
555
- s(:nil))
567
+ s(:nil)))
556
568
 
557
- s(:or,
558
- locals_declare,
559
- block)
569
+ s(:begin,
570
+ s(:or,
571
+ locals_declare,
572
+ block))
560
573
  end
561
574
  end
562
575
 
@@ -575,18 +588,20 @@ module RubyNext
575
588
 
576
589
  return rest if tail.empty?
577
590
 
578
- s(:and,
579
- rest,
580
- array_rest_element(*tail, -(size - 1)))
591
+ s(:begin,
592
+ s(:and,
593
+ rest,
594
+ array_rest_element(*tail, -(size - 1))))
581
595
  end
582
596
 
583
597
  def array_rest_element(head, *tail, index)
584
598
  send("#{head.type}_array_element", head, index).then do |node|
585
599
  next node if tail.empty?
586
600
 
587
- s(:and,
588
- node,
589
- array_rest_element(*tail, index + 1))
601
+ s(:begin,
602
+ s(:and,
603
+ node,
604
+ array_rest_element(*tail, index + 1)))
590
605
  end
591
606
  end
592
607
 
@@ -610,7 +625,7 @@ module RubyNext
610
625
  children = node.children.map do |child, i|
611
626
  send :"#{child.type}_array_element", child, index
612
627
  end
613
- s(:or, *children)
628
+ s(:begin, s(:or, *children))
614
629
  end
615
630
 
616
631
  def match_var_array_element(node, index)
@@ -661,18 +676,20 @@ module RubyNext
661
676
  elsif specified_key_names.empty?
662
677
  hash_element(*node.children)
663
678
  else
664
- s(:and,
665
- having_hash_keys(specified_key_names),
666
- hash_element(*node.children))
679
+ s(:begin,
680
+ s(:and,
681
+ having_hash_keys(specified_key_names),
682
+ hash_element(*node.children)))
667
683
  end
668
684
 
669
685
  predicates.pop
670
686
 
671
687
  next dnode if right.nil?
672
688
 
673
- s(:and,
674
- dnode,
675
- right)
689
+ s(:begin,
690
+ s(:and,
691
+ dnode,
692
+ right))
676
693
  end
677
694
  end
678
695
 
@@ -715,7 +732,7 @@ module RubyNext
715
732
  # Duplicate the source hash when matching **rest, 'cause we mutate it
716
733
  hash_dup =
717
734
  if @hash_match_rest
718
- s(:lvasgn, locals[:hash], s(:send, s(:lvar, locals[:hash, :src]), :dup))
735
+ s(:begin, s(:lvasgn, locals[:hash], s(:send, s(:lvar, locals[:hash, :src]), :dup)))
719
736
  else
720
737
  s(:true)
721
738
  end
@@ -728,29 +745,33 @@ module RubyNext
728
745
  key_names = keys.children.map { |node| node.children.last }
729
746
  predicates.push locals[:hash]
730
747
 
731
- s(:lvasgn, deconstruct_name,
748
+ s(:begin, s(:lvasgn, deconstruct_name,
732
749
  s(:send,
733
- matchee, :deconstruct_keys, keys)).then do |dnode|
750
+ matchee, :deconstruct_keys, keys))).then do |dnode|
734
751
  next dnode if respond_to_checked
735
752
 
736
753
  s(:and,
737
754
  respond_check,
738
- s(:and,
739
- s(:or,
740
- dnode,
741
- s(:true)),
742
- s(:or,
743
- s(:send,
744
- s(:const, nil, :Hash), :===, s(:lvar, deconstruct_name)),
745
- raise_error(:TypeError, "#deconstruct_keys must return Hash"))))
755
+ s(:begin,
756
+ s(:and,
757
+ s(:begin,
758
+ s(:or,
759
+ dnode,
760
+ s(:true))),
761
+ s(:begin,
762
+ s(:or,
763
+ s(:send,
764
+ s(:const, nil, :Hash), :===, s(:lvar, deconstruct_name)),
765
+ raise_error(:TypeError, "#deconstruct_keys must return Hash"))))))
746
766
  end.then do |dnode|
747
767
  predicates.hash_deconstructed(dnode, key_names)
748
768
  end.then do |dnode|
749
769
  next dnode unless @hash_match_rest
750
770
 
751
- s(:and,
752
- dnode,
753
- hash_dup)
771
+ s(:begin,
772
+ s(:and,
773
+ dnode,
774
+ hash_dup))
754
775
  end
755
776
  end
756
777
 
@@ -780,9 +801,10 @@ module RubyNext
780
801
 
781
802
  next node if right.nil?
782
803
 
783
- s(:and,
784
- node,
785
- right)
804
+ s(:begin,
805
+ s(:and,
806
+ node,
807
+ right))
786
808
  end
787
809
  end
788
810
 
@@ -792,7 +814,7 @@ module RubyNext
792
814
  end
793
815
 
794
816
  def match_alt_hash_element(node, key)
795
- element_node = s(:lvasgn, locals[:hash, :el], hash_value_at(key))
817
+ element_node = s(:begin, s(:lvasgn, locals[:hash, :el], hash_value_at(key)))
796
818
 
797
819
  children = locals.with(hash_element: locals[:hash, :el]) do
798
820
  node.children.map do |child, i|
@@ -800,11 +822,14 @@ module RubyNext
800
822
  end
801
823
  end
802
824
 
803
- s(:and,
804
- s(:or,
805
- element_node,
806
- s(:true)),
807
- s(:or, *children))
825
+ s(:begin,
826
+ s(:and,
827
+ s(:begin,
828
+ s(:or,
829
+ element_node,
830
+ s(:true))),
831
+ s(:begin,
832
+ s(:or, *children))))
808
833
  end
809
834
 
810
835
  def match_as_hash_element(node, key)
@@ -862,9 +887,10 @@ module RubyNext
862
887
  node = predicates.hash_key(hash_has_key(key, hash), key)
863
888
 
864
889
  keys.reduce(node) do |res, key|
865
- s(:and,
866
- res,
867
- predicates.hash_key(hash_has_key(key, hash), key))
890
+ s(:begin,
891
+ s(:and,
892
+ res,
893
+ predicates.hash_key(hash_has_key(key, hash), key)))
868
894
  end
869
895
  end
870
896
 
@@ -873,9 +899,10 @@ module RubyNext
873
899
  def with_guard(node, guard)
874
900
  return node unless guard
875
901
 
876
- s(:and,
877
- node,
878
- guard.children[0]).then do |expr|
902
+ s(:begin,
903
+ s(:and,
904
+ node,
905
+ guard.children[0])).then do |expr|
879
906
  next expr unless guard.type == :unless_guard
880
907
  s(:send, expr, :!)
881
908
  end
@@ -933,10 +960,10 @@ module RubyNext
933
960
  deconstructed_keys[key] = :"k#{deconstructed_keys.size}"
934
961
  end
935
962
 
936
- # Unparser generates `do .. end` blocks, we want to
963
+ # Unparser generates `do .. end` or `{ ... }` multiline blocks, we want to
937
964
  # have single-line blocks with `{ ... }`.
938
965
  def inline_blocks(source)
939
- source.gsub(/do \|_, __i__\|\n\s*([^\n]+)\n\s*end/, '{ |_, __i__| \1 }')
966
+ source.gsub(/(?:do|{) \|_, __i__\|\n\s*([^\n]+)\n\s*(?:end|})/, '{ |_, __i__| \1 }')
940
967
  end
941
968
  end
942
969
  end