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 +4 -4
- data/CHANGELOG.md +22 -0
- data/README.md +3 -0
- data/bin/reparse +19 -0
- data/bin/transform +22 -8
- data/lib/.rbnext/2.3/ruby-next/commands/nextify.rb +4 -1
- data/lib/.rbnext/2.3/ruby-next/language/eval.rb +1 -1
- data/lib/.rbnext/2.3/ruby-next/language/rewriters/base.rb +6 -5
- data/lib/.rbnext/2.3/ruby-next/language/rewriters/endless_range.rb +1 -1
- data/lib/.rbnext/2.3/ruby-next/language/rewriters/pattern_matching.rb +119 -92
- data/lib/.rbnext/2.3/ruby-next/language/rewriters/right_hand_assignment.rb +117 -0
- data/lib/.rbnext/2.3/ruby-next/utils.rb +1 -1
- data/lib/ruby-next/commands/nextify.rb +3 -0
- data/lib/ruby-next/language/rewriters/args_forward.rb +1 -1
- data/lib/ruby-next/language/rewriters/base.rb +2 -1
- data/lib/ruby-next/language/rewriters/numbered_params.rb +6 -2
- data/lib/ruby-next/language/rewriters/pattern_matching.rb +117 -90
- data/lib/ruby-next/language/rewriters/right_hand_assignment.rb +82 -10
- data/lib/ruby-next/language/rewriters/safe_navigation.rb +30 -26
- data/lib/ruby-next/rubocop.rb +76 -0
- data/lib/ruby-next/version.rb +1 -1
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 34691e69e3f0725ece379addac8297e0b69e9ed0a55fb1a06bfe3ca970213eae
|
4
|
+
data.tar.gz: 23edfba446641d2658d754f3678eb79de8ee332a4d481d4714887769392ad272
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d41912b15fd77ed3a1d2d2665a3375a212a1815e26e85724d2e0960af1daa5c714b126efca1c5621dc76b16af3d612c35a077be3472ca607548a757dea253ac
|
7
|
+
data.tar.gz: 02d860b6d0730f48b990c6c8dd9a3ef49e022ea7a0ae637a64cd0c29a74ee1e6c2b0f4cdf0ed25886029a49d9e2df8044b9e016aead9733ca322fd3579093949
|
data/CHANGELOG.md
CHANGED
@@ -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.
|
data/bin/reparse
ADDED
@@ -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)
|
data/bin/transform
CHANGED
@@ -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
|
23
|
+
File.read(ARGV.shift)
|
17
24
|
else
|
18
|
-
ARGV
|
25
|
+
ARGV.shift
|
19
26
|
end
|
20
27
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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, **
|
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?
|
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?
|
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?
|
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?
|
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?
|
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?
|
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
|
-
|
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
|
-
((!((
|
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(:
|
289
|
-
|
290
|
-
|
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?
|
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?
|
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(:
|
382
|
-
|
383
|
-
|
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(:
|
399
|
-
|
400
|
-
|
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(:
|
409
|
-
s(:
|
410
|
-
|
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(:
|
433
|
-
|
434
|
-
|
435
|
-
|
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(:
|
452
|
-
|
453
|
-
|
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(:
|
472
|
-
s(:
|
473
|
-
s(:
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
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(:
|
489
|
-
|
490
|
-
|
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(:
|
530
|
-
|
531
|
-
|
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(:
|
536
|
-
|
537
|
-
|
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(:
|
558
|
-
|
559
|
-
|
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(:
|
579
|
-
|
580
|
-
|
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(:
|
588
|
-
|
589
|
-
|
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(:
|
665
|
-
|
666
|
-
|
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(:
|
674
|
-
|
675
|
-
|
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(:
|
739
|
-
s(:
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
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(:
|
752
|
-
|
753
|
-
|
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(:
|
784
|
-
|
785
|
-
|
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(:
|
804
|
-
s(:
|
805
|
-
|
806
|
-
|
807
|
-
|
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(:
|
866
|
-
|
867
|
-
|
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(:
|
877
|
-
|
878
|
-
|
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`
|
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
|