ruby-next-parser 3.0.1.0 → 3.1.1.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.
@@ -96,7 +96,7 @@ class Next
96
96
  attr_accessor :static_env
97
97
  attr_accessor :force_utf32
98
98
 
99
- attr_accessor :cond, :cmdarg, :in_kwarg, :context, :command_start
99
+ attr_accessor :cond, :cmdarg, :context, :command_start
100
100
 
101
101
  attr_accessor :tokens, :comments
102
102
 
@@ -519,7 +519,8 @@ class Next
519
519
  c_nl_zlen = c_nl | zlen;
520
520
  c_line = any - c_nl_zlen;
521
521
 
522
- c_unicode = c_any - 0x00..0x7f;
522
+ c_ascii = 0x00..0x7f;
523
+ c_unicode = c_any - c_ascii;
523
524
  c_upper = [A-Z];
524
525
  c_lower = [a-z_] | c_unicode;
525
526
  c_alpha = c_lower | c_upper;
@@ -706,6 +707,11 @@ class Next
706
707
 
707
708
  action unescape_char {
708
709
  codepoint = @source_pts[p - 1]
710
+
711
+ if @version >= 30 && (codepoint == 117 || codepoint == 85) # 'u' or 'U'
712
+ diagnostic :fatal, :invalid_escape
713
+ end
714
+
709
715
  if (@escape = ESCAPES[codepoint]).nil?
710
716
  @escape = encode_escape(@source_buffer.slice(p - 1))
711
717
  end
@@ -733,12 +739,14 @@ class Next
733
739
 
734
740
  maybe_escaped_char = (
735
741
  '\\' c_any %unescape_char
742
+ | '\\x' xdigit{1,2} % { @escape = encode_escape(tok(p - 2, p).to_i(16)) } %slash_c_char
736
743
  | ( c_any - [\\] ) %read_post_meta_or_ctrl_char
737
744
  );
738
745
 
739
746
  maybe_escaped_ctrl_char = ( # why?!
740
747
  '\\' c_any %unescape_char %slash_c_char
741
748
  | '?' % { @escape = "\x7f" }
749
+ | '\\x' xdigit{1,2} % { @escape = encode_escape(tok(p - 2, p).to_i(16)) } %slash_c_char
742
750
  | ( c_any - [\\?] ) %read_post_meta_or_ctrl_char %slash_c_char
743
751
  );
744
752
 
@@ -930,6 +938,10 @@ class Next
930
938
  # b"
931
939
  # must be parsed as "ab"
932
940
  current_literal.extend_string(tok.gsub("\\\n".freeze, ''.freeze), @ts, @te)
941
+ elsif current_literal.regexp? && @version >= 31 && %w[c C m M].include?(escaped_char)
942
+ # Ruby >= 3.1 escapes \c- and \m chars, that's the only escape sequence
943
+ # supported by regexes so far, so it needs a separate branch.
944
+ current_literal.extend_string(@escape, @ts, @te)
933
945
  elsif current_literal.regexp?
934
946
  # Regular expressions should include escape sequences in their
935
947
  # escaped form. On the other hand, escaped newlines are removed (in cases like "\\C-\\\n\\M-x")
@@ -1402,7 +1414,7 @@ class Next
1402
1414
  ':'
1403
1415
  => { fhold; fgoto expr_beg; };
1404
1416
 
1405
- '%s' c_any
1417
+ '%s' (c_ascii - [A-Za-z0-9])
1406
1418
  => {
1407
1419
  if version?(23)
1408
1420
  type, delimiter = tok[0..-2], tok[-1].chr
@@ -1431,6 +1443,18 @@ class Next
1431
1443
  => { emit(:tLABEL, tok(@ts, @te - 2), @ts, @te - 1)
1432
1444
  fhold; fnext expr_labelarg; fbreak; };
1433
1445
 
1446
+ '...'
1447
+ => {
1448
+ if @version >= 31 && @context.in_argdef
1449
+ emit(:tBDOT3, '...'.freeze)
1450
+ # emit(:tNL, "\n".freeze, @te - 1, @te)
1451
+ fnext expr_end; fbreak;
1452
+ else
1453
+ p -= 3;
1454
+ fgoto expr_end;
1455
+ end
1456
+ };
1457
+
1434
1458
  w_space_comment;
1435
1459
 
1436
1460
  c_any
@@ -1754,14 +1778,14 @@ class Next
1754
1778
  };
1755
1779
 
1756
1780
  # %<string>
1757
- '%' ( any - [A-Za-z] )
1781
+ '%' ( c_ascii - [A-Za-z0-9] )
1758
1782
  => {
1759
1783
  type, delimiter = @source_buffer.slice(@ts).chr, tok[-1].chr
1760
1784
  fgoto *push_literal(type, delimiter, @ts);
1761
1785
  };
1762
1786
 
1763
1787
  # %w(we are the people)
1764
- '%' [A-Za-z]+ c_any
1788
+ '%' [A-Za-z] (c_ascii - [A-Za-z0-9])
1765
1789
  => {
1766
1790
  type, delimiter = tok[0..-2], tok[-1].chr
1767
1791
  fgoto *push_literal(type, delimiter, @ts);
@@ -2035,19 +2059,38 @@ class Next
2035
2059
  fnext expr_beg; fbreak;
2036
2060
  };
2037
2061
 
2038
- '...'
2062
+ '...' c_nl?
2039
2063
  => {
2064
+ # Here we scan and conditionally emit "\n":
2065
+ # + if it's there
2066
+ # + and emitted we do nothing
2067
+ # + and not emitted we return `p` to "\n" to process it on the next scan
2068
+ # + if it's not there we do nothing
2069
+ followed_by_nl = @te - 1 == @newline_s
2070
+ nl_emitted = false
2071
+ dots_te = followed_by_nl ? @te - 1 : @te
2072
+
2040
2073
  if @version >= 30
2041
2074
  if @lambda_stack.any? && @lambda_stack.last + 1 == @paren_nest
2042
2075
  # To reject `->(...)` like `->...`
2043
- emit(:tDOT3)
2076
+ emit(:tDOT3, '...'.freeze, @ts, dots_te)
2044
2077
  else
2045
- emit(:tBDOT3)
2078
+ emit(:tBDOT3, '...'.freeze, @ts, dots_te)
2079
+
2080
+ if @version >= 31 && followed_by_nl && @context.in_argdef
2081
+ emit(:tNL, @te - 1, @te)
2082
+ nl_emitted = true
2083
+ end
2046
2084
  end
2047
2085
  elsif @version >= 27
2048
- emit(:tBDOT3)
2086
+ emit(:tBDOT3, '...'.freeze, @ts, dots_te)
2049
2087
  else
2050
- emit(:tDOT3)
2088
+ emit(:tDOT3, '...'.freeze, @ts, dots_te)
2089
+ end
2090
+
2091
+ if followed_by_nl && !nl_emitted
2092
+ # return "\n" to process it on the next scan
2093
+ fhold;
2051
2094
  end
2052
2095
 
2053
2096
  fnext expr_beg; fbreak;
@@ -2119,7 +2162,7 @@ class Next
2119
2162
 
2120
2163
  w_newline
2121
2164
  => {
2122
- if @in_kwarg
2165
+ if @context.in_kwarg
2123
2166
  fhold; fgoto expr_end;
2124
2167
  else
2125
2168
  fgoto line_begin;
@@ -2526,6 +2569,28 @@ class Next
2526
2569
  end
2527
2570
  };
2528
2571
 
2572
+ c_space* '..'
2573
+ => {
2574
+ emit(:tNL, nil, @newline_s, @newline_s + 1)
2575
+ if @version < 27
2576
+ fhold; fnext line_begin; fbreak;
2577
+ else
2578
+ emit(:tBDOT2)
2579
+ fnext expr_beg; fbreak;
2580
+ end
2581
+ };
2582
+
2583
+ c_space* '...'
2584
+ => {
2585
+ emit(:tNL, nil, @newline_s, @newline_s + 1)
2586
+ if @version < 27
2587
+ fhold; fnext line_begin; fbreak;
2588
+ else
2589
+ emit(:tBDOT3)
2590
+ fnext expr_beg; fbreak;
2591
+ end
2592
+ };
2593
+
2529
2594
  c_space* %{ tm = p } ('.' | '&.')
2530
2595
  => { p = tm - 1; fgoto expr_end; };
2531
2596
 
@@ -5,7 +5,7 @@ require "parser/meta"
5
5
  module Parser
6
6
  # Parser metadata
7
7
  module Meta
8
- NEXT_NODE_TYPES = (NODE_TYPES + %i[meth_ref ipair]).to_set.freeze
8
+ NEXT_NODE_TYPES = (NODE_TYPES + %i[meth_ref]).to_set.freeze
9
9
 
10
10
  remove_const(:NODE_TYPES)
11
11
  const_set(:NODE_TYPES, NEXT_NODE_TYPES)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Parser
4
- NEXT_VERSION = "3.0.1.0"
4
+ NEXT_VERSION = "3.1.1.1"
5
5
  end