ruby_parser 3.7.3 → 3.8.0

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.
@@ -680,9 +680,9 @@ class RubyLexer
680
680
  end
681
681
 
682
682
  def process_label text
683
- result = process_symbol text
684
- result[0] = :tLABEL
685
- result
683
+ symbol = text[1..-3].gsub(ESC) { unescape $1 }
684
+
685
+ result(:expr_labelarg, :tLABEL, [symbol, self.lineno])
686
686
  end
687
687
 
688
688
  def process_token text
@@ -1074,7 +1074,8 @@ class RubyLexer
1074
1074
  end
1075
1075
 
1076
1076
  def ruby22?
1077
- Ruby22Parser === parser
1077
+ Ruby22Parser === parser or
1078
+ Ruby23Parser === parser
1078
1079
  end
1079
1080
 
1080
1081
  def process_string # TODO: rewrite / remove
@@ -61,7 +61,7 @@ rule
61
61
  | bol? /\=begin(?=\s)/ process_begin
62
62
  | /\=(?=begin\b)/ { result arg_state, TOKENS[text], text }
63
63
 
64
- ruby22_label? /\"(#{SIMPLE_STRING})\":/o process_label
64
+ ruby22_label? /\"#{SIMPLE_STRING}\":/o process_label
65
65
  /\"(#{SIMPLE_STRING})\"/o { result :expr_end, :tSTRING, text[1..-2].gsub(ESC) { unescape $1 } }
66
66
  /\"/ { string STR_DQUOTE; result nil, :tSTRING_BEG, text }
67
67
 
@@ -133,6 +133,7 @@ was_label? /\'#{SSTRING}\':?/o process_label_or_string
133
133
  | /\&\&\=/ { result(:expr_beg, :tOP_ASGN, "&&") }
134
134
  | /\&\&/ { result(:expr_beg, :tANDOP, "&&") }
135
135
  | /\&\=/ { result(:expr_beg, :tOP_ASGN, "&" ) }
136
+ | /\&\./ { result(:expr_dot, :tLONELY, "&.") }
136
137
  | /\&/ process_amper
137
138
 
138
139
  /\// process_slash
@@ -111,7 +111,7 @@ class RubyLexer
111
111
  when text = ss.scan(/\=(?=begin\b)/) then
112
112
  action { result arg_state, TOKENS[text], text }
113
113
  end # group /=/
114
- when ruby22_label? && (text = ss.scan(/\"(#{SIMPLE_STRING})\":/o)) then
114
+ when ruby22_label? && (text = ss.scan(/\"#{SIMPLE_STRING}\":/o)) then
115
115
  process_label text
116
116
  when text = ss.scan(/\"(#{SIMPLE_STRING})\"/o) then
117
117
  action { result :expr_end, :tSTRING, text[1..-2].gsub(ESC) { unescape $1 } }
@@ -232,6 +232,8 @@ class RubyLexer
232
232
  action { result(:expr_beg, :tANDOP, "&&") }
233
233
  when ss.skip(/\&\=/) then
234
234
  action { result(:expr_beg, :tOP_ASGN, "&" ) }
235
+ when ss.skip(/\&\./) then
236
+ action { result(:expr_dot, :tLONELY, "&.") }
235
237
  when text = ss.scan(/\&/) then
236
238
  process_amper text
237
239
  end # group /&/
@@ -3,4 +3,5 @@ require 'ruby19_parser'
3
3
  require 'ruby20_parser'
4
4
  require 'ruby21_parser'
5
5
  require 'ruby22_parser'
6
+ require 'ruby23_parser'
6
7
  require 'ruby_parser_extras'
@@ -6,6 +6,8 @@ class Ruby20Parser
6
6
  class Ruby21Parser
7
7
  #elif defined(RUBY22)
8
8
  class Ruby22Parser
9
+ #elif defined(RUBY23)
10
+ class Ruby23Parser
9
11
  #endif
10
12
 
11
13
  token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
@@ -25,12 +27,15 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
25
27
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
26
28
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
27
29
  tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
28
- #if defined(RUBY21) || defined(RUBY22)
30
+ #if defined(RUBY21) || defined(RUBY22) || defined(RUBY23))
29
31
  tRATIONAL tIMAGINARY
30
32
  #endif
31
- #if defined(RUBY22)
33
+ #if defined(RUBY22 || defined(RUBY23))
32
34
  tLABEL_END
33
35
  #endif
36
+ #if defined(RUBY23)
37
+ tLONELY
38
+ #endif
34
39
 
35
40
  prechigh
36
41
  right tBANG tTILDE tUPLUS
@@ -222,7 +227,7 @@ rule
222
227
  result = new_masgn val[0], val[2], :wrap
223
228
  }
224
229
  | mlhs tEQL mrhs
225
- #elif defined(RUBY21) || defined(RUBY22)
230
+ #elif defined(RUBY21) || defined(RUBY22 || defined(RUBY23))
226
231
  | mlhs tEQL mrhs_arg
227
232
  #endif
228
233
  {
@@ -312,6 +317,13 @@ rule
312
317
  {
313
318
  result = new_call val[0], val[2].to_sym, val[3]
314
319
  }
320
+ #if defined(RUBY23)
321
+ | primary_value tLONELY operation2 command_args =tLOWEST
322
+ {
323
+ result = new_call val[0], val[2].to_sym, val[3]
324
+ result[0] = :safe_call
325
+ }
326
+ #endif
315
327
  | primary_value tDOT operation2 command_args cmd_brace_block
316
328
  {
317
329
  recv, _, msg, args, block = val
@@ -509,6 +521,16 @@ rule
509
521
  {
510
522
  result = s(:attrasgn, val[0], :"#{val[2]}=")
511
523
  }
524
+ #if defined(RUBY23)
525
+ | primary_value tLONELY tIDENTIFIER
526
+ {
527
+ result = s(:safe_attrasgn, val[0], :"#{val[2]}=")
528
+ }
529
+ | primary_value tLONELY tCONSTANT
530
+ {
531
+ result = s(:safe_attrasgn, val[0], :"#{val[2]}=")
532
+ }
533
+ #endif
512
534
  | primary_value tCOLON2 tIDENTIFIER
513
535
  {
514
536
  result = s(:attrasgn, val[0], :"#{val[2]}=")
@@ -707,7 +729,7 @@ rule
707
729
  result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
708
730
  }
709
731
  | tUMINUS_NUM tFLOAT tPOW arg
710
- #elif defined(RUBY21) || defined(RUBY22)
732
+ #elif defined(RUBY21) || defined(RUBY22 || defined(RUBY23))
711
733
  | tUMINUS_NUM simple_numeric tPOW arg
712
734
  #endif
713
735
  {
@@ -926,7 +948,7 @@ rule
926
948
  result = self.list_append val[0], s(:splat, val[3])
927
949
  }
928
950
 
929
- #if defined(RUBY21) || defined(RUBY22)
951
+ #if defined(RUBY21) || defined(RUBY22 || defined(RUBY23))
930
952
  mrhs_arg: mrhs
931
953
  {
932
954
  result = new_masgn_arg val[0]
@@ -1574,6 +1596,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1574
1596
  {
1575
1597
  result = new_call val[0], val[2].to_sym, val[3]
1576
1598
  }
1599
+ #if defined(RUBY23)
1600
+ | primary_value tLONELY operation2 opt_paren_args
1601
+ {
1602
+ result = new_call val[0], val[2].to_sym, val[3]
1603
+ result[0] = :safe_call
1604
+ }
1605
+ #endif
1577
1606
  | primary_value tCOLON2 operation2 paren_args
1578
1607
  {
1579
1608
  result = new_call val[0], val[2].to_sym, val[3]
@@ -1586,6 +1615,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1586
1615
  {
1587
1616
  result = new_call val[0], :call, val[2]
1588
1617
  }
1618
+ #if defined(RUBY23)
1619
+ | primary_value tLONELY paren_args
1620
+ {
1621
+ result = new_call val[0], :call, val[2]
1622
+ result[0] = :safe_call
1623
+ }
1624
+ #endif
1589
1625
  | primary_value tCOLON2 paren_args
1590
1626
  {
1591
1627
  result = new_call val[0], :call, val[2]
@@ -1888,7 +1924,7 @@ regexp_contents: none
1888
1924
  {
1889
1925
  #if defined(RUBY20)
1890
1926
  # TODO: tRCURLY -> tSTRING_DEND
1891
- #elif defined(RUBY21) || defined(RUBY22)
1927
+ #elif defined(RUBY21) || defined(RUBY22 || defined(RUBY23))
1892
1928
  # TODO: tRCURLY -> tSTRING_END
1893
1929
  #endif
1894
1930
  _, memo, stmt, _ = val
@@ -1960,7 +1996,7 @@ regexp_contents: none
1960
1996
  numeric: tINTEGER
1961
1997
  | tFLOAT
1962
1998
  | tUMINUS_NUM tINTEGER =tLOWEST
1963
- #elif defined(RUBY21) || defined(RUBY22)
1999
+ #elif defined(RUBY21) || defined(RUBY22 || defined(RUBY23))
1964
2000
  numeric: simple_numeric
1965
2001
  | tUMINUS_NUM simple_numeric
1966
2002
  #endif
@@ -1974,7 +2010,7 @@ regexp_contents: none
1974
2010
  #endif
1975
2011
  }
1976
2012
 
1977
- #if defined(RUBY21) || defined(RUBY22)
2013
+ #if defined(RUBY21) || defined(RUBY22) || defined(RUBY23))
1978
2014
  simple_numeric: tINTEGER
1979
2015
  | tFLOAT
1980
2016
  | tRATIONAL
@@ -2173,7 +2209,7 @@ keyword_variable: kNIL { result = s(:nil) }
2173
2209
  result = identifier
2174
2210
  }
2175
2211
 
2176
- #if defined(RUBY22)
2212
+ #if defined(RUBY22) || defined(RUBY23))
2177
2213
  f_arg_asgn: f_norm_arg
2178
2214
 
2179
2215
  f_arg_item: f_arg_asgn
@@ -2217,7 +2253,7 @@ keyword_variable: kNIL { result = s(:nil) }
2217
2253
 
2218
2254
  #if defined(RUBY20)
2219
2255
  f_kw: tLABEL arg_value
2220
- #elif defined(RUBY21) || defined(RUBY22)
2256
+ #elif defined(RUBY21) || defined(RUBY22) || defined(RUBY23)
2221
2257
  f_label: tLABEL
2222
2258
 
2223
2259
  f_kw: f_label arg_value
@@ -2230,7 +2266,7 @@ keyword_variable: kNIL { result = s(:nil) }
2230
2266
 
2231
2267
  result = s(:array, s(:kwarg, identifier, val[1]))
2232
2268
  }
2233
- #if defined(RUBY21) || defined(RUBY22)
2269
+ #if defined(RUBY21) || defined(RUBY22) || defined(RUBY23)
2234
2270
  | f_label
2235
2271
  {
2236
2272
  label, _ = val[0] # TODO: fix lineno?
@@ -2243,7 +2279,7 @@ keyword_variable: kNIL { result = s(:nil) }
2243
2279
 
2244
2280
  #if defined(RUBY20)
2245
2281
  f_block_kw: tLABEL primary_value
2246
- #elif defined(RUBY21) || defined(RUBY22)
2282
+ #elif defined(RUBY21) || defined(RUBY22) || defined(RUBY23)
2247
2283
  f_block_kw: f_label primary_value
2248
2284
  #endif
2249
2285
  {
@@ -2254,7 +2290,7 @@ keyword_variable: kNIL { result = s(:nil) }
2254
2290
 
2255
2291
  result = s(:array, s(:kwarg, identifier, val[1]))
2256
2292
  }
2257
- #if defined(RUBY21) || defined(RUBY22)
2293
+ #if defined(RUBY21) || defined(RUBY22) || defined(RUBY23)
2258
2294
  | f_label
2259
2295
  {
2260
2296
  label, _ = val[0] # TODO: fix lineno?
@@ -2294,7 +2330,7 @@ keyword_variable: kNIL { result = s(:nil) }
2294
2330
  f_opt: tIDENTIFIER tEQL arg_value
2295
2331
  #elif defined(RUBY21)
2296
2332
  f_opt: f_norm_arg tEQL arg_value
2297
- #elif defined(RUBY22)
2333
+ #elif defined(RUBY22) || defined(RUBY23)
2298
2334
  f_opt: f_arg_asgn tEQL arg_value
2299
2335
  #endif
2300
2336
  {
@@ -2306,7 +2342,7 @@ keyword_variable: kNIL { result = s(:nil) }
2306
2342
  f_block_opt: tIDENTIFIER tEQL primary_value
2307
2343
  #elif defined(RUBY21)
2308
2344
  f_block_opt: f_norm_arg tEQL primary_value
2309
- #elif defined(RUBY22)
2345
+ #elif defined(RUBY22) || defined(RUBY23)
2310
2346
  f_block_opt: f_arg_asgn tEQL primary_value
2311
2347
  #endif
2312
2348
  {
@@ -2407,7 +2443,7 @@ keyword_variable: kNIL { result = s(:nil) }
2407
2443
  {
2408
2444
  result = s(:array, s(:lit, val[0][0].to_sym), val[1])
2409
2445
  }
2410
- #if defined(RUBY22)
2446
+ #if defined(RUBY22) || defined(RUBY23)
2411
2447
  | tSTRING_BEG string_contents tLABEL_END arg_value
2412
2448
  {
2413
2449
  _, sym, _, value = val
@@ -91,7 +91,7 @@ class RPStringScanner < StringScanner
91
91
  end
92
92
 
93
93
  module RubyParserStuff
94
- VERSION = "3.7.3" unless constants.include? "VERSION" # SIGH
94
+ VERSION = "3.8.0" unless constants.include? "VERSION" # SIGH
95
95
 
96
96
  attr_accessor :lexer, :in_def, :in_single, :file
97
97
  attr_reader :env, :comments
@@ -932,7 +932,7 @@ module RubyParserStuff
932
932
  rhs = value_expr rhs
933
933
 
934
934
  case lhs[0]
935
- when :lasgn, :iasgn, :cdecl, :cvdecl, :gasgn, :cvasgn, :attrasgn then
935
+ when :lasgn, :iasgn, :cdecl, :cvdecl, :gasgn, :cvasgn, :attrasgn, :safe_attrasgn then
936
936
  lhs << rhs
937
937
  when :const then
938
938
  lhs[0] = :cdecl
@@ -1320,6 +1320,10 @@ module RubyParserStuff
1320
1320
  end
1321
1321
  end
1322
1322
 
1323
+ class Ruby23Parser < Racc::Parser
1324
+ include RubyParserStuff
1325
+ end
1326
+
1323
1327
  class Ruby22Parser < Racc::Parser
1324
1328
  include RubyParserStuff
1325
1329
  end
@@ -1354,11 +1358,12 @@ class RubyParser
1354
1358
  @p20 = Ruby20Parser.new
1355
1359
  @p21 = Ruby21Parser.new
1356
1360
  @p22 = Ruby22Parser.new
1361
+ @p23 = Ruby23Parser.new
1357
1362
  end
1358
1363
 
1359
1364
  def process s, f = "(string)", t = 10
1360
1365
  e = nil
1361
- [@p22, @p21, @p20, @p19, @p18].each do |parser|
1366
+ [@p23, @p22, @p21, @p20, @p19, @p18].each do |parser|
1362
1367
  begin
1363
1368
  return parser.process s, f, t
1364
1369
  rescue Racc::ParseError, RubyParser::SyntaxError => exc
@@ -1376,6 +1381,7 @@ class RubyParser
1376
1381
  @p20.reset
1377
1382
  @p21.reset
1378
1383
  @p22.reset
1384
+ @p23.reset
1379
1385
  end
1380
1386
 
1381
1387
  def self.for_current_ruby
@@ -1390,6 +1396,8 @@ class RubyParser
1390
1396
  Ruby21Parser.new
1391
1397
  when /^2.2/ then
1392
1398
  Ruby22Parser.new
1399
+ when /^2.3/ then
1400
+ Ruby23Parser.new
1393
1401
  else
1394
1402
  raise "unrecognized RUBY_VERSION #{RUBY_VERSION}"
1395
1403
  end
@@ -245,6 +245,21 @@ class TestRubyLexer < Minitest::Test
245
245
  assert_lex3("&&=", nil, :tOP_ASGN, "&&", :expr_beg)
246
246
  end
247
247
 
248
+ def test_yylex_and_dot
249
+ setup_lexer_class Ruby23Parser
250
+
251
+ assert_lex3("&.", nil, :tLONELY, "&.", :expr_dot)
252
+ end
253
+
254
+ def test_yylex_and_dot_call
255
+ setup_lexer_class Ruby23Parser
256
+
257
+ assert_lex3("x&.y", nil,
258
+ :tIDENTIFIER, "x", :expr_cmdarg,
259
+ :tLONELY, "&.", :expr_dot,
260
+ :tIDENTIFIER, "y")
261
+ end
262
+
248
263
  def test_yylex_and_arg
249
264
  self.lex_state = :expr_arg
250
265
 
@@ -2653,10 +2668,34 @@ class TestRubyLexer < Minitest::Test
2653
2668
  assert_lex("{'a':1}",
2654
2669
  s(:hash, s(:lit, :a), s(:lit, 1)),
2655
2670
 
2656
- :tLBRACE, "{", :expr_beg, 0, 1,
2657
- :tLABEL, "a", :expr_end, 0, 1,
2658
- :tINTEGER, 1, :expr_end, 0, 1,
2659
- :tRCURLY, "}", :expr_endarg, 0, 0)
2671
+ :tLBRACE, "{", :expr_beg, 0, 1,
2672
+ :tLABEL, "a", :expr_labelarg, 0, 1,
2673
+ :tINTEGER, 1, :expr_end, 0, 1,
2674
+ :tRCURLY, "}", :expr_endarg, 0, 0)
2675
+ end
2676
+
2677
+ def test_yylex_hash_colon_quoted_symbol_22
2678
+ setup_lexer_class Ruby22Parser
2679
+
2680
+ assert_lex("{'abc': :b}",
2681
+ s(:hash, s(:lit, :abc), s(:lit, :b)),
2682
+
2683
+ :tLBRACE, "{", :expr_beg, 0, 1,
2684
+ :tLABEL, "abc", :expr_labelarg, 0, 1,
2685
+ :tSYMBOL, "b", :expr_end, 0, 1,
2686
+ :tRCURLY, "}", :expr_endarg, 0, 0)
2687
+ end
2688
+
2689
+ def test_yylex_hash_colon_double_quoted_symbol_22
2690
+ setup_lexer_class Ruby22Parser
2691
+
2692
+ assert_lex('{"abc": :b}',
2693
+ s(:hash, s(:lit, :abc), s(:lit, :b)),
2694
+
2695
+ :tLBRACE, "{", :expr_beg, 0, 1,
2696
+ :tLABEL, "abc", :expr_labelarg, 0, 1,
2697
+ :tSYMBOL, "b", :expr_end, 0, 1,
2698
+ :tRCURLY, "}", :expr_endarg, 0, 0)
2660
2699
  end
2661
2700
 
2662
2701
  def test_ruby21_new_numbers
@@ -961,6 +961,10 @@ module TestRubyParserShared
961
961
  Ruby22Parser === self.processor
962
962
  end
963
963
 
964
+ def ruby23
965
+ Ruby23Parser === self.processor
966
+ end
967
+
964
968
  def test_bug_comma
965
969
  val = if ruby18 then
966
970
  s(:lit, 100)
@@ -1016,7 +1020,7 @@ module TestRubyParserShared
1016
1020
  rb = "not(a)"
1017
1021
  pt = if ruby18 then
1018
1022
  s(:not, s(:call, nil, :a))
1019
- elsif ruby19 or ruby20 or ruby21 or ruby22 then
1023
+ elsif ruby19 or ruby20 or ruby21 or ruby22 or ruby23 then
1020
1024
  s(:call, s(:call, nil, :a), :"!")
1021
1025
  else
1022
1026
  raise "wtf"
@@ -3384,9 +3388,78 @@ class TestRuby22Parser < RubyParserTestCase
3384
3388
  rb = "a ? \"\": b"
3385
3389
  assert_parse rb, pt
3386
3390
  end
3391
+
3392
+ def test_quoted_symbol_keys
3393
+ rb = "{ 'a': :b }"
3394
+ pt = s(:hash, s(:lit, :a), s(:lit, :b))
3395
+
3396
+ assert_parse rb, pt
3397
+ end
3398
+
3399
+ def test_quoted_symbol_hash_arg
3400
+ rb = "puts 'a': {}"
3401
+ pt = s(:call, nil, :puts, s(:hash, s(:lit, :a), s(:hash)))
3402
+
3403
+ assert_parse rb, pt
3404
+ end
3387
3405
  end
3388
3406
 
3389
- [18, 19, 20, 21, 22].each do |v|
3407
+ class TestRuby23Parser < RubyParserTestCase
3408
+ include TestRubyParserShared
3409
+ include TestRubyParserShared19to22
3410
+ include TestRubyParserShared20to22
3411
+
3412
+ def setup
3413
+ super
3414
+
3415
+ self.processor = Ruby23Parser.new
3416
+ end
3417
+
3418
+ def test_safe_call
3419
+ rb = "a&.b"
3420
+ pt = s(:safe_call, s(:call, nil, :a), :b)
3421
+
3422
+ assert_parse rb, pt
3423
+ end
3424
+
3425
+ def test_safe_calls
3426
+ rb = "a&.b&.c(1)"
3427
+ pt = s(:safe_call, s(:safe_call, s(:call, nil, :a), :b), :c, s(:lit, 1))
3428
+
3429
+ assert_parse rb, pt
3430
+ end
3431
+
3432
+ def test_safe_attrasgn
3433
+ rb = "a&.b = 1"
3434
+ pt = s(:safe_attrasgn, s(:call, nil, :a), :"b=", s(:lit, 1))
3435
+
3436
+ assert_parse rb, pt
3437
+ end
3438
+
3439
+ def test_safe_attrasgn_constant
3440
+ rb = "a&.B = 1"
3441
+ pt = s(:safe_attrasgn, s(:call, nil, :a), :"B=", s(:lit, 1))
3442
+
3443
+ assert_parse rb, pt
3444
+ end
3445
+
3446
+ def test_safe_call_dot_parens
3447
+ rb = "a&.()"
3448
+ pt = s(:safe_call, s(:call, nil, :a), :call)
3449
+
3450
+ assert_parse rb, pt
3451
+ end
3452
+
3453
+ def test_safe_call_operator
3454
+ rb = "a&.> 1"
3455
+ pt = s(:safe_call, s(:call, nil, :a), :>, s(:lit, 1))
3456
+
3457
+ assert_parse rb, pt
3458
+ end
3459
+ end
3460
+
3461
+
3462
+ [18, 19, 20, 21, 22, 23].each do |v|
3390
3463
  describe "block args arity #{v}" do
3391
3464
  attr_accessor :parser
3392
3465