ruby-next-core 0.14.0 → 0.14.1
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 +4 -0
- data/lib/.rbnext/2.3/ruby-next/language/rewriters/2.7/pattern_matching.rb +78 -37
- data/lib/.rbnext/2.7/ruby-next/language/rewriters/2.7/pattern_matching.rb +1061 -0
- data/lib/ruby-next/language/rewriters/2.7/pattern_matching.rb +78 -37
- data/lib/ruby-next/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8f084701e3c87e432518f6367d883b9524dbc002d77352793b912504a63e8d0
|
4
|
+
data.tar.gz: bc44011f4183dd2133f259f07dc7a40c4be5dbd4cf2f85e35efb525463011ace
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eabbb2bc0ccfa86f033eabce8001d208638a3995c7f112c29ed0e5f3142597bc60d87112899e7d383b09739c7c4cbe2eff06d10c58df7577cf12f80d4cb19c4d
|
7
|
+
data.tar.gz: 000c76da160d8dba1231121b7e71b335da2d9775240bfc7a9fb2201ca55d6ac366f47f1c918a3c5ebb46abdcc90857b0c3a9d221455ed6eff68965f5b8f905e9
|
data/CHANGELOG.md
CHANGED
@@ -243,6 +243,7 @@ module RubyNext
|
|
243
243
|
|
244
244
|
@deconstructed_keys = {}
|
245
245
|
@predicates = Predicates::CaseIn.new
|
246
|
+
@lvars = []
|
246
247
|
|
247
248
|
matchee_ast =
|
248
249
|
s(:begin, s(:lvasgn, MATCHEE, node.children[0]))
|
@@ -272,6 +273,7 @@ module RubyNext
|
|
272
273
|
|
273
274
|
@deconstructed_keys = {}
|
274
275
|
@predicates = Predicates::Noop.new
|
276
|
+
@lvars = []
|
275
277
|
|
276
278
|
matchee =
|
277
279
|
s(:begin, s(:lvasgn, MATCHEE, node.children[0]))
|
@@ -282,10 +284,12 @@ module RubyNext
|
|
282
284
|
arr: MATCHEE_ARR,
|
283
285
|
hash: MATCHEE_HASH
|
284
286
|
) do
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
287
|
+
with_declared_locals do
|
288
|
+
send(
|
289
|
+
:"#{node.children[1].type}_clause",
|
290
|
+
node.children[1]
|
291
|
+
)
|
292
|
+
end.then do |node|
|
289
293
|
s(:begin,
|
290
294
|
s(:or,
|
291
295
|
node,
|
@@ -311,6 +315,7 @@ module RubyNext
|
|
311
315
|
|
312
316
|
@deconstructed_keys = {}
|
313
317
|
@predicates = Predicates::Noop.new
|
318
|
+
@lvars = []
|
314
319
|
|
315
320
|
matchee =
|
316
321
|
s(:begin, s(:lvasgn, MATCHEE, node.children[0]))
|
@@ -321,10 +326,12 @@ module RubyNext
|
|
321
326
|
arr: MATCHEE_ARR,
|
322
327
|
hash: MATCHEE_HASH
|
323
328
|
) do
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
329
|
+
with_declared_locals do
|
330
|
+
send(
|
331
|
+
:"#{node.children[1].type}_clause",
|
332
|
+
node.children[1]
|
333
|
+
)
|
334
|
+
end
|
328
335
|
end
|
329
336
|
|
330
337
|
node.updated(
|
@@ -395,13 +402,15 @@ module RubyNext
|
|
395
402
|
def build_when_clause(clause)
|
396
403
|
predicates.reset!
|
397
404
|
[
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
+
with_declared_locals do
|
406
|
+
with_guard(
|
407
|
+
send(
|
408
|
+
:"#{clause.children[0].type}_clause",
|
409
|
+
clause.children[0]
|
410
|
+
),
|
411
|
+
clause.children[1] # guard
|
412
|
+
)
|
413
|
+
end,
|
405
414
|
process(clause.children[2] || s(:nil)) # expression
|
406
415
|
].then do |children|
|
407
416
|
s(:when, *children)
|
@@ -442,7 +451,7 @@ module RubyNext
|
|
442
451
|
var = node.children[0]
|
443
452
|
return s(:true) if var == :_
|
444
453
|
|
445
|
-
check_match_var_alternation!(var)
|
454
|
+
check_match_var_alternation!(var)
|
446
455
|
|
447
456
|
s(:begin,
|
448
457
|
s(:or,
|
@@ -541,11 +550,10 @@ module RubyNext
|
|
541
550
|
def array_find(head, *nodes, tail)
|
542
551
|
index = s(:lvar, :__i__)
|
543
552
|
|
544
|
-
match_vars = []
|
545
|
-
|
546
553
|
head_match =
|
547
554
|
unless head.children.empty?
|
548
|
-
|
555
|
+
# we only need to call this to track the lvar usage
|
556
|
+
build_var_assignment(head.children[0].children[0])
|
549
557
|
|
550
558
|
arr_take = s(:send,
|
551
559
|
s(:lvar, locals[:arr]),
|
@@ -557,16 +565,19 @@ module RubyNext
|
|
557
565
|
|
558
566
|
tail_match =
|
559
567
|
unless tail.children.empty?
|
560
|
-
|
568
|
+
# we only need to call this to track the lvar usage
|
569
|
+
build_var_assignment(tail.children[0].children[0])
|
561
570
|
|
562
571
|
match_var_clause(tail.children[0], arr_slice(index + nodes.size, -1))
|
563
572
|
end
|
564
573
|
|
565
574
|
nodes.each do |node|
|
566
575
|
if node.type == :match_var
|
567
|
-
|
576
|
+
# we only need to call this to track the lvar usage
|
577
|
+
build_var_assignment(node.children[0])
|
568
578
|
elsif node.type == :match_as
|
569
|
-
|
579
|
+
# we only need to call this to track the lvar usage
|
580
|
+
build_var_assignment(node.children[1].children[0])
|
570
581
|
end
|
571
582
|
end
|
572
583
|
|
@@ -594,19 +605,7 @@ module RubyNext
|
|
594
605
|
s(:args,
|
595
606
|
s(:arg, :_),
|
596
607
|
s(:arg, :__i__)),
|
597
|
-
pattern)
|
598
|
-
next block if match_vars.empty?
|
599
|
-
|
600
|
-
# We need to declare match vars outside of `find` block
|
601
|
-
locals_declare = s(:begin, s(:masgn,
|
602
|
-
s(:mlhs, *match_vars),
|
603
|
-
s(:nil)))
|
604
|
-
|
605
|
-
s(:begin,
|
606
|
-
s(:or,
|
607
|
-
locals_declare,
|
608
|
-
block))
|
609
|
-
end
|
608
|
+
pattern)
|
610
609
|
end
|
611
610
|
|
612
611
|
def array_match_rest(index, node, *tail)
|
@@ -649,6 +648,14 @@ module RubyNext
|
|
649
648
|
end
|
650
649
|
end
|
651
650
|
|
651
|
+
def find_pattern_array_element(node, index)
|
652
|
+
element = arr_item_at(index)
|
653
|
+
locals.with(arr: locals[:arr, index]) do
|
654
|
+
predicates.push :"i#{index}"
|
655
|
+
find_pattern_clause(node, element).tap { predicates.pop }
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
652
659
|
def hash_pattern_array_element(node, index)
|
653
660
|
element = arr_item_at(index)
|
654
661
|
locals.with(hash: locals[:arr, index]) do
|
@@ -829,6 +836,15 @@ module RubyNext
|
|
829
836
|
end
|
830
837
|
end
|
831
838
|
|
839
|
+
def find_pattern_hash_element(node, key)
|
840
|
+
element = hash_value_at(key)
|
841
|
+
key_index = deconstructed_key(key)
|
842
|
+
locals.with(arr: locals[:hash, key_index]) do
|
843
|
+
predicates.push :"k#{key_index}"
|
844
|
+
find_pattern_clause(node, element).tap { predicates.pop }
|
845
|
+
end
|
846
|
+
end
|
847
|
+
|
832
848
|
def hash_element(head, *tail)
|
833
849
|
send("#{head.type}_hash_element", head).then do |node|
|
834
850
|
next node if tail.empty?
|
@@ -948,6 +964,24 @@ module RubyNext
|
|
948
964
|
end
|
949
965
|
end
|
950
966
|
|
967
|
+
def with_declared_locals
|
968
|
+
lvars.clear
|
969
|
+
node = yield
|
970
|
+
|
971
|
+
return node if lvars.empty?
|
972
|
+
|
973
|
+
# We need to declare match lvars outside of the outer `find` block,
|
974
|
+
# so we do that for that whole pattern
|
975
|
+
locals_declare = s(:begin, s(:masgn,
|
976
|
+
s(:mlhs, *lvars.uniq.map { |_1| s(:lvasgn, _1) }),
|
977
|
+
s(:nil)))
|
978
|
+
|
979
|
+
s(:begin,
|
980
|
+
s(:or,
|
981
|
+
locals_declare,
|
982
|
+
node))
|
983
|
+
end
|
984
|
+
|
951
985
|
def no_matching_pattern
|
952
986
|
raise_error(
|
953
987
|
:NoMatchingPatternError,
|
@@ -982,13 +1016,17 @@ module RubyNext
|
|
982
1016
|
|
983
1017
|
private
|
984
1018
|
|
985
|
-
attr_reader :deconstructed_keys, :predicates
|
1019
|
+
attr_reader :deconstructed_keys, :predicates, :lvars
|
986
1020
|
|
987
1021
|
# Raise SyntaxError if match-var is used within alternation
|
988
1022
|
# https://github.com/ruby/ruby/blob/672213ef1ca2b71312084057e27580b340438796/compile.c#L5900
|
989
1023
|
def check_match_var_alternation!(name)
|
990
1024
|
return unless locals.key?(ALTERNATION_MARKER)
|
991
1025
|
|
1026
|
+
if name.is_a?(::Parser::AST::Node)
|
1027
|
+
raise ::SyntaxError, "illegal variable in alternative pattern (#{name.children.first})"
|
1028
|
+
end
|
1029
|
+
|
992
1030
|
return if name.start_with?("_")
|
993
1031
|
|
994
1032
|
raise ::SyntaxError, "illegal variable in alternative pattern (#{name})"
|
@@ -1008,7 +1046,10 @@ module RubyNext
|
|
1008
1046
|
|
1009
1047
|
# Value could be omitted for mass assignment
|
1010
1048
|
def build_var_assignment(var, value = nil)
|
1011
|
-
|
1049
|
+
unless var.is_a?(::Parser::AST::Node)
|
1050
|
+
lvars << var
|
1051
|
+
return s(:lvasgn, *[var, value].compact)
|
1052
|
+
end
|
1012
1053
|
|
1013
1054
|
asign_type = :"#{var.type.to_s[0]}vasgn"
|
1014
1055
|
|