ruby-next-core 0.10.0 → 0.10.5
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 +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
|