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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55cb050984d91ee15965b5629bd998d7300af1051e7ad721f1dfed77fc6df7c7
4
- data.tar.gz: ac68a6f7da2b826b11a40be72948601f2d12ce8b1cd27ab9953977238c1e488d
3
+ metadata.gz: c8f084701e3c87e432518f6367d883b9524dbc002d77352793b912504a63e8d0
4
+ data.tar.gz: bc44011f4183dd2133f259f07dc7a40c4be5dbd4cf2f85e35efb525463011ace
5
5
  SHA512:
6
- metadata.gz: 7cd0de569637973ff61866733a6a3d59dac4e317bf5e522b23a88fc5af8941e4a072ae1dfbf26163a661c71911f7801545cad00134cd826d4913f684b03473e8
7
- data.tar.gz: 2ebf8f0a42bd0771cfbc2f2240a3844436d3f108e5cec292ec2cd7e3bebef0a332088357a892cf3cd2b0c6835e9f39679cc472cd6a0ac4d120850194d8f2e783
6
+ metadata.gz: eabbb2bc0ccfa86f033eabce8001d208638a3995c7f112c29ed0e5f3142597bc60d87112899e7d383b09739c7c4cbe2eff06d10c58df7577cf12f80d4cb19c4d
7
+ data.tar.gz: 000c76da160d8dba1231121b7e71b335da2d9775240bfc7a9fb2201ca55d6ac366f47f1c918a3c5ebb46abdcc90857b0c3a9d221455ed6eff68965f5b8f905e9
data/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.14.1 (2022-01-21)
6
+
7
+ - Fix nested find patterns transpiling. ([@palkan][])
8
+
5
9
  ## 0.14.0 🎄
6
10
 
7
11
  - Add `Integer.try_convert`. ([@palkan][])
@@ -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
- send(
286
- :"#{node.children[1].type}_clause",
287
- node.children[1]
288
- ).then do |node|
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
- send(
325
- :"#{node.children[1].type}_clause",
326
- node.children[1]
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
- with_guard(
399
- send(
400
- :"#{clause.children[0].type}_clause",
401
- clause.children[0]
402
- ),
403
- clause.children[1] # guard
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) unless var.is_a?(::Parser::AST::Node)
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
- match_vars << build_var_assignment(head.children[0].children[0])
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
- match_vars << build_var_assignment(tail.children[0].children[0])
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
- match_vars << build_var_assignment(node.children[0])
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
- match_vars << build_var_assignment(node.children[1].children[0])
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).then do |block|
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
- return s(:lvasgn, *[var, value].compact) unless var.is_a?(::Parser::AST::Node)
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