ruby_parser 3.4.1 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ruby_parser.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'ruby18_parser'
2
2
  require 'ruby19_parser'
3
3
  require 'ruby20_parser'
4
+ require 'ruby21_parser'
4
5
  require 'ruby_parser_extras'
@@ -91,7 +91,7 @@ class RPStringScanner < StringScanner
91
91
  end
92
92
 
93
93
  module RubyParserStuff
94
- VERSION = "3.4.1" unless constants.include? "VERSION" # SIGH
94
+ VERSION = "3.5.0" unless constants.include? "VERSION" # SIGH
95
95
 
96
96
  attr_accessor :lexer, :in_def, :in_single, :file
97
97
  attr_reader :env, :comments
@@ -240,6 +240,8 @@ module RubyParserStuff
240
240
  raise "unhandled: #{arg.sexp_type} in #{args.inspect}"
241
241
  end
242
242
  when Symbol then
243
+ name = arg.to_s.delete("&*")
244
+ self.env[name.to_sym] = :lvar unless name.empty?
243
245
  result << arg
244
246
  when ",", "|", ";", "(", ")", nil then
245
247
  # ignore
@@ -404,7 +406,7 @@ module RubyParserStuff
404
406
  def initialize(options = {})
405
407
  super()
406
408
 
407
- v = self.class.name[/1[89]|20/]
409
+ v = self.class.name[/1[89]|2[01]/]
408
410
 
409
411
  self.lexer = RubyLexer.new v && v.to_i
410
412
  self.lexer.parser = self
@@ -688,6 +690,12 @@ module RubyParserStuff
688
690
  result
689
691
  end
690
692
 
693
+ def new_masgn_arg rhs, wrap = false
694
+ rhs = value_expr(rhs)
695
+ rhs = s(:to_ary, rhs) if wrap # HACK: could be array if lhs isn't right
696
+ rhs
697
+ end
698
+
691
699
  def new_masgn lhs, rhs, wrap = false
692
700
  rhs = value_expr(rhs)
693
701
  rhs = lhs[1] ? s(:to_ary, rhs) : s(:array, rhs) if wrap
@@ -1290,6 +1298,10 @@ module RubyParserStuff
1290
1298
  end
1291
1299
  end
1292
1300
 
1301
+ class Ruby21Parser < Racc::Parser
1302
+ include RubyParserStuff
1303
+ end
1304
+
1293
1305
  class Ruby20Parser < Racc::Parser
1294
1306
  include RubyParserStuff
1295
1307
  end
@@ -1314,16 +1326,19 @@ class RubyParser
1314
1326
  @p18 = Ruby18Parser.new
1315
1327
  @p19 = Ruby19Parser.new
1316
1328
  @p20 = Ruby20Parser.new
1329
+ @p21 = Ruby21Parser.new
1317
1330
  end
1318
1331
 
1319
- def process(s, f = "(string)", t = 10) # parens for emacs *sigh*
1320
- @p20.process s, f, t
1321
- rescue Racc::ParseError, RubyParser::SyntaxError
1322
- begin
1323
- @p19.process s, f, t
1324
- rescue Racc::ParseError, RubyParser::SyntaxError
1325
- @p18.process s, f, t
1332
+ def process s, f = "(string)", t = 10
1333
+ e = nil
1334
+ [@p21, @p20, @p19, @p18].each do |parser|
1335
+ begin
1336
+ return parser.process s, f, t
1337
+ rescue Racc::ParseError, RubyParser::SyntaxError => exc
1338
+ e = exc
1339
+ end
1326
1340
  end
1341
+ raise e
1327
1342
  end
1328
1343
 
1329
1344
  alias :parse :process
@@ -1331,6 +1346,8 @@ class RubyParser
1331
1346
  def reset
1332
1347
  @p18.reset
1333
1348
  @p19.reset
1349
+ @p20.reset
1350
+ @p21.reset
1334
1351
  end
1335
1352
 
1336
1353
  def self.for_current_ruby
@@ -1341,6 +1358,8 @@ class RubyParser
1341
1358
  Ruby19Parser.new
1342
1359
  when /^2.0/ then
1343
1360
  Ruby20Parser.new
1361
+ when /^2.1/ then
1362
+ Ruby21Parser.new
1344
1363
  else
1345
1364
  raise "unrecognized RUBY_VERSION #{RUBY_VERSION}"
1346
1365
  end
@@ -2611,4 +2611,27 @@ class TestRubyLexer < Minitest::Test
2611
2611
  :tSTRING_END, nil, :expr_end, 0, 0)
2612
2612
  end
2613
2613
  end
2614
+
2615
+ def test_ruby21_new_numbers
2616
+ skip "Don't have imaginary and rational literal lexing yet"
2617
+
2618
+ setup_lexer_class Ruby21Parser
2619
+
2620
+ assert_lex3("10r", nil, :tRATIONAL, "10r", :expr_end)
2621
+ assert_lex3("1.5r", nil, :tRATIONAL, "1.5r", :expr_end)
2622
+
2623
+ assert_lex3("1i", nil, :tIMAGINARY, "1i", :expr_end)
2624
+ assert_lex3("1+2i", nil, :tIMAGINARY, "1+2i", :expr_end)
2625
+ assert_lex3("1.2+3.4i", nil, :tIMAGINARY, "1.2+3.4i", :expr_end)
2626
+ assert_lex3("4r+3i", nil, :tIMAGINARY, "4r+3i", :expr_end)
2627
+ assert_lex3("4r+3ri", nil, :tIMAGINARY, "4r+3i", :expr_end)
2628
+
2629
+ assert_lex3("4i+3r", nil, :tIMAGINARY, "4r+3i", :expr_end) # HACK
2630
+ assert_lex3("1i+2ri", nil, :tIMAGINARY, "4r+3i", :expr_end) # HACK
2631
+
2632
+ assert_lex3("1+2ri", nil, :tIMAGINARY, "1+3ri", :expr_end)
2633
+ refute_lex("1+2ir", :tINTEGER, 1)
2634
+
2635
+ flunk
2636
+ end
2614
2637
  end
@@ -720,6 +720,18 @@ module TestRubyParserShared
720
720
  assert_parse rb, pt
721
721
  end
722
722
 
723
+ def test_parse_line_heredoc_evstr
724
+ skip "heredoc line numbers are just gonna be screwed for a while..."
725
+
726
+ rb = "<<-A\na\n\#{b}\nA"
727
+ pt = s(:dstr, "a\n",
728
+ s(:evstr,
729
+ s(:call, nil, :b).line(3)),
730
+ s(:str, "\n")).line(1)
731
+
732
+ assert_parse rb, pt
733
+ end
734
+
723
735
  def test_parse_line_iter_call_parens
724
736
  rb = "f(a) do |x, y|\n x + y\nend"
725
737
 
@@ -874,13 +886,15 @@ module TestRubyParserShared
874
886
  Ruby20Parser === self.processor
875
887
  end
876
888
 
889
+ def ruby21
890
+ Ruby21Parser === self.processor
891
+ end
892
+
877
893
  def test_bug_comma
878
894
  val = if ruby18 then
879
895
  s(:lit, 100)
880
- elsif ruby19 or ruby20 then
881
- s(:str, "d")
882
896
  else
883
- raise "wtf"
897
+ s(:str, "d")
884
898
  end
885
899
 
886
900
  rb = "if test ?d, dir then end"
@@ -931,7 +945,7 @@ module TestRubyParserShared
931
945
  rb = "not(a)"
932
946
  pt = if ruby18 then
933
947
  s(:not, s(:call, nil, :a))
934
- elsif ruby19 or ruby20 then
948
+ elsif ruby19 or ruby20 or ruby21 then
935
949
  s(:call, s(:call, nil, :a), :"!")
936
950
  else
937
951
  raise "wtf"
@@ -1333,15 +1347,6 @@ module TestRubyParserShared
1333
1347
  assert_parse rb, pt
1334
1348
  end
1335
1349
 
1336
- def test_aref_args_lit_assocs
1337
- skip if ruby18
1338
-
1339
- rb = "[1, 2 => 3]"
1340
- pt = s(:array, s(:lit, 1), s(:hash, s(:lit, 2), s(:lit, 3)))
1341
-
1342
- assert_parse rb, pt
1343
- end
1344
-
1345
1350
  def test_BEGIN
1346
1351
  rb = "BEGIN { 42 }"
1347
1352
  pt = s(:iter, s(:preexe), s(:args), s(:lit, 42))
@@ -1402,15 +1407,6 @@ module TestRubyParserShared
1402
1407
  assert_parse rb, pt
1403
1408
  end
1404
1409
 
1405
- def test_block_decomp_arg_splat
1406
- skip "not that smart yet" if ruby18 # HACK
1407
-
1408
- rb = "a { |(b, *)| }"
1409
- pt = s(:iter, s(:call, nil, :a), s(:args, s(:masgn, :b, :*)))
1410
-
1411
- assert_parse rb, pt
1412
- end
1413
-
1414
1410
  def test_masgn_arg_ident
1415
1411
  rb = "a, b.C = d"
1416
1412
  pt = s(:masgn,
@@ -1543,7 +1539,21 @@ module TestRubyParserShared
1543
1539
  end
1544
1540
  end
1545
1541
 
1546
- module TestRubyParserShared1920
1542
+ module TestRubyParserShared19to21
1543
+ def test_aref_args_lit_assocs
1544
+ rb = "[1, 2 => 3]"
1545
+ pt = s(:array, s(:lit, 1), s(:hash, s(:lit, 2), s(:lit, 3)))
1546
+
1547
+ assert_parse rb, pt
1548
+ end
1549
+
1550
+ def test_block_decomp_arg_splat
1551
+ rb = "a { |(b, *)| }"
1552
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:masgn, :b, :*)))
1553
+
1554
+ assert_parse rb, pt
1555
+ end
1556
+
1547
1557
  def test_block_call_operation_dot
1548
1558
  rb = "a.b c do end.d"
1549
1559
  pt = s(:call,
@@ -2015,9 +2025,8 @@ module TestRubyParserShared1920
2015
2025
  end
2016
2026
 
2017
2027
  def test_mlhs_keyword
2018
- skip "Breaks on 1.9 and 2.0 parser but valid" # HACK
2019
2028
  rb = "a.!=(true, true)"
2020
- pt = 42
2029
+ pt = s(:call, s(:call, nil, :a), :"!=", s(:true), s(:true))
2021
2030
 
2022
2031
  assert_parse rb, pt
2023
2032
  end
@@ -2030,6 +2039,70 @@ module TestRubyParserShared1920
2030
2039
  end
2031
2040
  end
2032
2041
 
2042
+ module TestRubyParserShared20to21
2043
+ def test_defn_kwarg_kwsplat
2044
+ rb = "def a(b: 1, **c) end"
2045
+ pt = s(:defn, :a, s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"), s(:nil))
2046
+
2047
+ assert_parse rb, pt
2048
+ end
2049
+
2050
+ def test_defn_kwarg_env
2051
+ rb = "def test(**testing) test_splat(**testing) end"
2052
+ pt = s(:defn, :test, s(:args, :"**testing"),
2053
+ s(:call, nil, :test_splat, s(:kwsplat, s(:lvar, :testing))))
2054
+
2055
+ assert_parse rb, pt
2056
+ end
2057
+
2058
+ def test_call_arg_kwsplat
2059
+ rb = "a(b, **1)"
2060
+ pt = s(:call, nil, :a, s(:call, nil, :b), s(:kwsplat, s(:lit, 1)))
2061
+
2062
+ assert_parse rb, pt
2063
+ end
2064
+
2065
+ def test_call_kwsplat
2066
+ rb = "a(**1)"
2067
+ pt = s(:call, nil, :a, s(:kwsplat, s(:lit, 1)))
2068
+
2069
+ assert_parse rb, pt
2070
+ end
2071
+
2072
+ def test_iter_kwarg
2073
+ rb = "a { |b: 1| }"
2074
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1))))
2075
+
2076
+ assert_parse rb, pt
2077
+ end
2078
+
2079
+ def test_iter_kwarg_kwsplat
2080
+ rb = "a { |b: 1, **c| }"
2081
+ pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"))
2082
+
2083
+ assert_parse rb, pt
2084
+ end
2085
+
2086
+ def test_block_kwarg_lvar
2087
+ rb = "bl { |kw: :val| kw }"
2088
+ pt = s(:iter, s(:call, nil, :bl), s(:args, s(:kwarg, :kw, s(:lit, :val))),
2089
+ s(:lvar, :kw))
2090
+
2091
+ assert_parse rb, pt
2092
+ end
2093
+
2094
+ def test_block_kwarg_lvar_multiple
2095
+ rb = "bl { |kw: :val, kw2: :val2 | kw }"
2096
+ pt = s(:iter, s(:call, nil, :bl),
2097
+ s(:args,
2098
+ s(:kwarg, :kw, s(:lit, :val)),
2099
+ s(:kwarg, :kw2, s(:lit, :val2))),
2100
+ s(:lvar, :kw))
2101
+
2102
+ assert_parse rb, pt
2103
+ end
2104
+ end
2105
+
2033
2106
  class TestRubyParser < Minitest::Test
2034
2107
  def test_parse
2035
2108
  processor = RubyParser.new
@@ -2268,7 +2341,7 @@ end
2268
2341
 
2269
2342
  class TestRuby19Parser < RubyParserTestCase
2270
2343
  include TestRubyParserShared
2271
- include TestRubyParserShared1920
2344
+ include TestRubyParserShared19to21
2272
2345
 
2273
2346
  def setup
2274
2347
  super
@@ -2868,7 +2941,8 @@ end
2868
2941
 
2869
2942
  class TestRuby20Parser < RubyParserTestCase
2870
2943
  include TestRubyParserShared
2871
- include TestRubyParserShared1920
2944
+ include TestRubyParserShared20to21
2945
+ include TestRubyParserShared19to21
2872
2946
 
2873
2947
  def setup
2874
2948
  super
@@ -2946,14 +3020,6 @@ class TestRuby20Parser < RubyParserTestCase
2946
3020
  assert_parse rb, pt
2947
3021
  end
2948
3022
 
2949
- def test_block_kwarg_lvar
2950
- rb = "bl { |kw: :val| kw }"
2951
- pt = s(:iter, s(:call, nil, :bl), s(:args, s(:kwarg, :kw, s(:lit, :val))),
2952
- s(:lvar, :kw))
2953
-
2954
- assert_parse rb, pt
2955
- end
2956
-
2957
3023
  def test_defn_powarg
2958
3024
  rb = "def f(**opts) end"
2959
3025
  pt = s(:defn, :f, s(:args, :"**opts"), s(:nil))
@@ -3027,54 +3093,58 @@ class TestRuby20Parser < RubyParserTestCase
3027
3093
  assert_parse rb, pt
3028
3094
  end
3029
3095
 
3030
- def test_defn_unary_not # TODO: this needs to work on 1.9
3031
- skip "Not yet"
3096
+ def test_defn_unary_not
3032
3097
  rb = "def !@; true; end" # I seriously HATE this
3033
3098
  pt = s(:defn, :"!@", s(:args), s(:true))
3034
3099
 
3035
3100
  assert_parse rb, pt
3036
3101
  end
3037
3102
 
3038
- def test_defn_kwarg_kwsplat
3039
- rb = "def a(b: 1, **c) end"
3040
- pt = s(:defn, :a, s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"), s(:nil))
3103
+ def test_iter_array_curly
3104
+ rb = "f :a, [:b] { |c, d| }" # yes, this is bad code... that's their problem
3105
+ pt = s(:iter,
3106
+ s(:call, nil, :f, s(:lit, :a), s(:array, s(:lit, :b))),
3107
+ s(:args, :c, :d))
3041
3108
 
3042
3109
  assert_parse rb, pt
3043
3110
  end
3111
+ end
3044
3112
 
3045
- def test_call_arg_kwsplat
3046
- rb = "a(b, **1)"
3047
- pt = s(:call, nil, :a, s(:call, nil, :b), s(:kwsplat, s(:lit, 1)))
3113
+ class TestRuby21Parser < RubyParserTestCase
3114
+ include TestRubyParserShared
3115
+ include TestRubyParserShared19to21
3116
+ include TestRubyParserShared20to21
3048
3117
 
3049
- assert_parse rb, pt
3118
+ def setup
3119
+ super
3120
+
3121
+ self.processor = Ruby21Parser.new
3050
3122
  end
3051
3123
 
3052
- def test_call_kwsplat
3053
- rb = "a(**1)"
3054
- pt = s(:call, nil, :a, s(:kwsplat, s(:lit, 1)))
3124
+ def test_f_kw
3125
+ rb = "def x k:42; end"
3126
+ pt = s(:defn, :x, s(:args, s(:kwarg, :k, s(:lit, 42))), s(:nil))
3055
3127
 
3056
3128
  assert_parse rb, pt
3057
3129
  end
3058
3130
 
3059
- def test_iter_kwarg
3060
- rb = "a { |b: 1| }"
3061
- pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1))))
3131
+ def test_f_kw__required
3132
+ rb = "def x k:; end"
3133
+ pt = s(:defn, :x, s(:args, s(:kwarg, :k)), s(:nil))
3062
3134
 
3063
3135
  assert_parse rb, pt
3064
3136
  end
3065
3137
 
3066
- def test_iter_kwarg_kwsplat
3067
- rb = "a { |b: 1, **c| }"
3068
- pt = s(:iter, s(:call, nil, :a), s(:args, s(:kwarg, :b, s(:lit, 1)), :"**c"))
3138
+ def test_block_kw
3139
+ rb = "-> (k:42) { }"
3140
+ pt = s(:iter, s(:call, nil, :lambda), s(:args, s(:kwarg, :k, s(:lit, 42))))
3069
3141
 
3070
3142
  assert_parse rb, pt
3071
3143
  end
3072
3144
 
3073
- def test_iter_array_curly
3074
- rb = "f :a, [:b] { |c, d| }" # yes, this is bad code... that's their problem
3075
- pt = s(:iter,
3076
- s(:call, nil, :f, s(:lit, :a), s(:array, s(:lit, :b))),
3077
- s(:args, :c, :d))
3145
+ def test_block_kw__required
3146
+ rb = "-> (k:) { }"
3147
+ pt = s(:iter, s(:call, nil, :lambda), s(:args, s(:kwarg, :k)))
3078
3148
 
3079
3149
  assert_parse rb, pt
3080
3150
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.1
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Davis
@@ -29,7 +29,7 @@ cert_chain:
29
29
  Y4evBVezr3SjXz08vPqRO5YRdO3zfeMT8gBjRqZjWJGMZ2lD4XNfrs7eky74CyZw
30
30
  xx3n58i0lQkBE1EpKE0lFu/y
31
31
  -----END CERTIFICATE-----
32
- date: 2014-02-14 00:00:00.000000000 Z
32
+ date: 2014-03-25 00:00:00.000000000 Z
33
33
  dependencies:
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: sexp_processor
@@ -51,14 +51,14 @@ dependencies:
51
51
  requirements:
52
52
  - - ~>
53
53
  - !ruby/object:Gem::Version
54
- version: '5.2'
54
+ version: '5.3'
55
55
  type: :development
56
56
  prerelease: false
57
57
  version_requirements: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: '5.2'
61
+ version: '5.3'
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: rdoc
64
64
  requirement: !ruby/object:Gem::Requirement
@@ -121,14 +121,14 @@ dependencies:
121
121
  requirements:
122
122
  - - ~>
123
123
  - !ruby/object:Gem::Version
124
- version: '3.9'
124
+ version: '3.10'
125
125
  type: :development
126
126
  prerelease: false
127
127
  version_requirements: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ~>
130
130
  - !ruby/object:Gem::Version
131
- version: '3.9'
131
+ version: '3.10'
132
132
  description: |-
133
133
  ruby_parser (RP) is a ruby parser written in pure ruby (utilizing
134
134
  racc--which does by default use a C extension). RP's output is
@@ -182,6 +182,8 @@ files:
182
182
  - lib/ruby19_parser.y
183
183
  - lib/ruby20_parser.rb
184
184
  - lib/ruby20_parser.y
185
+ - lib/ruby21_parser.rb
186
+ - lib/ruby21_parser.y
185
187
  - lib/ruby_lexer.rb
186
188
  - lib/ruby_lexer.rex
187
189
  - lib/ruby_lexer.rex.rb
@@ -211,7 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
211
213
  - !ruby/object:Gem::Version
212
214
  version: '0'
213
215
  requirements: []
214
- rubyforge_project: ruby_parser
216
+ rubyforge_project:
215
217
  rubygems_version: 2.2.1
216
218
  signing_key:
217
219
  specification_version: 4