ruby_parser 3.7.3 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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