parser 1.4.2 → 2.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,6 +6,7 @@ class TestLexer < MiniTest::Unit::TestCase
6
6
  def setup_lexer(version)
7
7
  @lex = Parser::Lexer.new(version)
8
8
 
9
+ @lex.comments = []
9
10
  @lex.diagnostics = Parser::Diagnostic::Engine.new
10
11
  @lex.diagnostics.all_errors_are_fatal = true
11
12
  # @lex.diagnostics.consumer = lambda { |diag| $stderr.puts "", diag.render }
@@ -376,7 +377,10 @@ class TestLexer < MiniTest::Unit::TestCase
376
377
  :tINTEGER, 1,
377
378
  :tNL, nil,
378
379
  :tINTEGER, 2)
379
- assert_equal "# one\n# two\n", @lex.comments
380
+
381
+ assert_equal 2, @lex.comments.length
382
+ assert_equal '# one', @lex.comments[0].text
383
+ assert_equal '# two', @lex.comments[1].text
380
384
  end
381
385
 
382
386
  def test_comment_expr_beg
@@ -388,7 +392,8 @@ class TestLexer < MiniTest::Unit::TestCase
388
392
  def test_comment_begin
389
393
  util_lex_token("=begin\nblah\nblah\n=end\n42",
390
394
  :tINTEGER, 42)
391
- assert_equal "=begin\nblah\nblah\n=end\n", @lex.comments
395
+ assert_equal 1, @lex.comments.length
396
+ assert_equal "=begin\nblah\nblah\n=end\n", @lex.comments[0].text
392
397
  end
393
398
 
394
399
  def test_comment_begin_bad
@@ -409,12 +414,16 @@ class TestLexer < MiniTest::Unit::TestCase
409
414
 
410
415
  def test_comment_begin_space
411
416
  util_lex_token("=begin blah\nblah\n=end\n")
412
- assert_equal "=begin blah\nblah\n=end\n", @lex.comments
417
+
418
+ assert_equal 1, @lex.comments.length
419
+ assert_equal "=begin blah\nblah\n=end\n", @lex.comments[0].text
413
420
  end
414
421
 
415
422
  def test_comment_end_space_and_text
416
423
  util_lex_token("=begin blah\nblah\n=end blab\n")
417
- assert_equal "=begin blah\nblah\n=end blab\n", @lex.comments
424
+
425
+ assert_equal 1, @lex.comments.length
426
+ assert_equal "=begin blah\nblah\n=end blab\n", @lex.comments[0].text
418
427
  end
419
428
 
420
429
  def test_comment_eos
@@ -481,16 +490,15 @@ class TestLexer < MiniTest::Unit::TestCase
481
490
  :kEND, "end")
482
491
  end
483
492
 
484
- # TODO
485
- # def test_do_cond
486
- # @lex.cond.push true
493
+ def test_do_cond
494
+ @lex.cond.push true
487
495
 
488
- # util_lex_token("x do 42 end",
489
- # :tIDENTIFIER, "x",
490
- # :kDO_COND, "do",
491
- # :tINTEGER, 42,
492
- # :kEND, "end")
493
- # end
496
+ util_lex_token("x do 42 end",
497
+ :tIDENTIFIER, "x",
498
+ :kDO_COND, "do",
499
+ :tINTEGER, 42,
500
+ :kEND, "end")
501
+ end
494
502
 
495
503
  def test_dot
496
504
  util_lex_token ".", :tDOT, "."
@@ -1219,7 +1227,7 @@ class TestLexer < MiniTest::Unit::TestCase
1219
1227
  end
1220
1228
 
1221
1229
  def test_plus
1222
- util_lex_token("1 + 1", # TODO state?
1230
+ util_lex_token("1 + 1",
1223
1231
  :tINTEGER, 1,
1224
1232
  :tPLUS, "+",
1225
1233
  :tINTEGER, 1)
@@ -2103,6 +2111,239 @@ class TestLexer < MiniTest::Unit::TestCase
2103
2111
  :tRBRACK, "]")
2104
2112
  end
2105
2113
 
2114
+ #
2115
+ # Tests for whitespace.
2116
+ #
2117
+
2118
+ def test_whitespace_fname
2119
+ @lex.state = :expr_fname
2120
+ util_lex_token('class',
2121
+ :kCLASS, 'class')
2122
+
2123
+ @lex.state = :expr_fname
2124
+ util_lex_token(' class',
2125
+ :kCLASS, 'class')
2126
+
2127
+ @lex.state = :expr_fname
2128
+ util_lex_token("\nclass",
2129
+ :kCLASS, 'class')
2130
+
2131
+ @lex.state = :expr_fname
2132
+ util_lex_token("\\\nclass",
2133
+ :kCLASS, 'class')
2134
+
2135
+ @lex.state = :expr_fname
2136
+ util_lex_token("#foo\nclass",
2137
+ :kCLASS, 'class')
2138
+ end
2139
+
2140
+ def test_whitespace_endfn
2141
+ setup_lexer(21)
2142
+
2143
+ @lex.state = :expr_endfn
2144
+ util_lex_token('foo:',
2145
+ :tLABEL, 'foo')
2146
+
2147
+ @lex.state = :expr_endfn
2148
+ util_lex_token(' foo:',
2149
+ :tLABEL, 'foo')
2150
+
2151
+ @lex.state = :expr_endfn
2152
+ util_lex_token("\nfoo:",
2153
+ :tNL, nil,
2154
+ :tIDENTIFIER, 'foo',
2155
+ :tCOLON, ':')
2156
+
2157
+ @lex.state = :expr_endfn
2158
+ util_lex_token("\\\nfoo:",
2159
+ :tLABEL, 'foo')
2160
+
2161
+ @lex.state = :expr_endfn
2162
+ util_lex_token("#foo\nfoo:",
2163
+ :tNL, nil,
2164
+ :tIDENTIFIER, 'foo',
2165
+ :tCOLON, ':')
2166
+ end
2167
+
2168
+ def test_whitespace_dot
2169
+ @lex.state = :expr_dot
2170
+ util_lex_token('class',
2171
+ :tIDENTIFIER, 'class')
2172
+
2173
+ @lex.state = :expr_dot
2174
+ util_lex_token(' class',
2175
+ :tIDENTIFIER, 'class')
2176
+
2177
+ @lex.state = :expr_dot
2178
+ util_lex_token("\nclass",
2179
+ :tIDENTIFIER, 'class')
2180
+
2181
+ @lex.state = :expr_dot
2182
+ util_lex_token("\\\nclass",
2183
+ :tIDENTIFIER, 'class')
2184
+
2185
+ @lex.state = :expr_dot
2186
+ util_lex_token("#foo\nclass",
2187
+ :tIDENTIFIER, 'class')
2188
+ end
2189
+
2190
+ def test_whitespace_arg
2191
+ @lex.state = :expr_arg
2192
+ util_lex_token('+',
2193
+ :tPLUS, '+')
2194
+
2195
+ @lex.state = :expr_arg
2196
+ util_lex_token(' +',
2197
+ :tUPLUS, '+')
2198
+
2199
+ @lex.state = :expr_arg
2200
+ util_lex_token("\n+",
2201
+ :tNL, nil,
2202
+ :tUPLUS, '+')
2203
+
2204
+ @lex.state = :expr_arg
2205
+ util_lex_token("\\\n+",
2206
+ :tUPLUS, '+')
2207
+
2208
+ @lex.state = :expr_arg
2209
+ util_lex_token("\\\n +",
2210
+ :tUPLUS, '+')
2211
+
2212
+ @lex.state = :expr_arg
2213
+ util_lex_token("#foo\n+",
2214
+ :tNL, nil,
2215
+ :tUPLUS, '+')
2216
+ end
2217
+
2218
+ def test_whitespace_endarg
2219
+ @lex.state = :expr_endarg
2220
+ util_lex_token('{',
2221
+ :tLBRACE_ARG, '{')
2222
+
2223
+ @lex.state = :expr_endarg
2224
+ util_lex_token(' {',
2225
+ :tLBRACE_ARG, '{')
2226
+
2227
+ @lex.state = :expr_endarg
2228
+ util_lex_token("\n{",
2229
+ :tNL, nil,
2230
+ :tLBRACE, '{')
2231
+
2232
+ @lex.state = :expr_endarg
2233
+ util_lex_token("\\\n{",
2234
+ :tLBRACE_ARG, '{')
2235
+
2236
+ @lex.state = :expr_endarg
2237
+ util_lex_token("#foo\n{",
2238
+ :tNL, nil,
2239
+ :tLBRACE, '{')
2240
+ end
2241
+
2242
+ def test_whitespace_mid
2243
+ @lex.state = :expr_mid
2244
+ util_lex_token('+',
2245
+ :tUPLUS, '+')
2246
+
2247
+ @lex.state = :expr_mid
2248
+ util_lex_token(' +',
2249
+ :tUPLUS, '+')
2250
+
2251
+ @lex.state = :expr_mid
2252
+ util_lex_token("\n+",
2253
+ :tNL, nil,
2254
+ :tUPLUS, '+')
2255
+
2256
+ @lex.state = :expr_mid
2257
+ util_lex_token("\\\n+",
2258
+ :tUPLUS, '+')
2259
+
2260
+ @lex.state = :expr_mid
2261
+ util_lex_token("#foo\n+",
2262
+ :tNL, nil,
2263
+ :tUPLUS, '+')
2264
+ end
2265
+
2266
+ def test_whitespace_beg
2267
+ @lex.state = :expr_beg
2268
+ util_lex_token('+',
2269
+ :tUPLUS, '+')
2270
+
2271
+ @lex.state = :expr_beg
2272
+ util_lex_token(' +',
2273
+ :tUPLUS, '+')
2274
+
2275
+ @lex.state = :expr_beg
2276
+ util_lex_token("\n+",
2277
+ :tUPLUS, '+')
2278
+
2279
+ @lex.state = :expr_beg
2280
+ util_lex_token("\\\n+",
2281
+ :tUPLUS, '+')
2282
+
2283
+ @lex.state = :expr_beg
2284
+ util_lex_token("#foo\n+",
2285
+ :tUPLUS, '+')
2286
+ end
2287
+
2288
+ def test_whitespace_value
2289
+ setup_lexer(20)
2290
+
2291
+ @lex.state = :expr_value
2292
+ util_lex_token('a:b',
2293
+ :tIDENTIFIER, 'a',
2294
+ :tSYMBOL, 'b')
2295
+
2296
+ @lex.state = :expr_value
2297
+ util_lex_token(' a:b',
2298
+ :tIDENTIFIER, 'a',
2299
+ :tSYMBOL, 'b')
2300
+
2301
+ @lex.state = :expr_value
2302
+ util_lex_token("\na:b",
2303
+ :tLABEL, 'a',
2304
+ :tIDENTIFIER, 'b')
2305
+
2306
+ @lex.state = :expr_value
2307
+ util_lex_token("\\\na:b",
2308
+ :tIDENTIFIER, 'a',
2309
+ :tSYMBOL, 'b')
2310
+
2311
+ @lex.state = :expr_value
2312
+ util_lex_token("#foo\na:b",
2313
+ :tLABEL, 'a',
2314
+ :tIDENTIFIER, 'b')
2315
+ end
2316
+
2317
+ def test_whitespace_end
2318
+ @lex.state = :expr_end
2319
+ util_lex_token('+ 1',
2320
+ :tPLUS, '+',
2321
+ :tINTEGER, 1)
2322
+
2323
+ @lex.state = :expr_end
2324
+ util_lex_token(' + 1',
2325
+ :tPLUS, '+',
2326
+ :tINTEGER, 1)
2327
+
2328
+ @lex.state = :expr_end
2329
+ util_lex_token("\n+ 1",
2330
+ :tNL, nil,
2331
+ :tUPLUS, '+',
2332
+ :tINTEGER, 1)
2333
+
2334
+ @lex.state = :expr_end
2335
+ util_lex_token("\\\n+ 1",
2336
+ :tPLUS, '+',
2337
+ :tINTEGER, 1)
2338
+
2339
+ @lex.state = :expr_end
2340
+ util_lex_token("#foo\n+ 1",
2341
+ :tNL, nil,
2342
+ :tUPLUS, '+',
2343
+ :tINTEGER, 1)
2344
+ end
2345
+
2346
+
2106
2347
  #
2107
2348
  # Tests for bugs.
2108
2349
  #
@@ -2307,7 +2548,7 @@ class TestLexer < MiniTest::Unit::TestCase
2307
2548
  def test_bug_expr_value_document
2308
2549
  util_lex_token("1;\n=begin\n=end",
2309
2550
  :tINTEGER, 1,
2310
- :tSEMI, ";")
2551
+ :tSEMI, ';')
2311
2552
  end
2312
2553
 
2313
2554
  def test_bug_expr_end_colon
@@ -2335,6 +2576,13 @@ class TestLexer < MiniTest::Unit::TestCase
2335
2576
  :tCONSTANT, 'Exception')
2336
2577
  end
2337
2578
 
2579
+ def test_bug_line_begin_label
2580
+ setup_lexer(19)
2581
+ util_lex_token("foo:bar",
2582
+ :tIDENTIFIER, 'foo',
2583
+ :tSYMBOL, 'bar')
2584
+ end
2585
+
2338
2586
  def test_bug_ragel_stack
2339
2587
  util_lex_token("\"\#{$2 ? $2 : 1}\"",
2340
2588
  :tSTRING_BEG, "\"",
@@ -434,7 +434,8 @@ class TestParser < MiniTest::Unit::TestCase
434
434
  %q[{ foo: 2 }],
435
435
  %q{^ begin
436
436
  | ^ end
437
- | ~~~~ expression (pair.sym)
437
+ | ^ operator (pair)
438
+ | ~~~ expression (pair.sym)
438
439
  | ~~~~~~ expression (pair)
439
440
  |~~~~~~~~~~ expression},
440
441
  ALL_VERSIONS - %w(1.8))
@@ -637,9 +638,9 @@ class TestParser < MiniTest::Unit::TestCase
637
638
  })
638
639
  end
639
640
 
640
- def test_cvdecl
641
+ def test_cvasgn
641
642
  assert_parses(
642
- s(:cvdecl, :@@var, s(:int, 10)),
643
+ s(:cvasgn, :@@var, s(:int, 10)),
643
644
  %q{@@var = 10},
644
645
  %q{~~~~~ name
645
646
  | ^ operator
@@ -647,17 +648,6 @@ class TestParser < MiniTest::Unit::TestCase
647
648
  })
648
649
  end
649
650
 
650
- def test_cvasgn
651
- assert_parses(
652
- s(:def, :a, s(:args),
653
- s(:cvasgn, :@@var, s(:int, 10))),
654
- %q{def a; @@var = 10; end},
655
- %q{ ~~~~~ name (cvasgn)
656
- | ^ operator (cvasgn)
657
- | ~~~~~~~~~~ expression (cvasgn)
658
- })
659
- end
660
-
661
651
  def test_gvasgn
662
652
  assert_parses(
663
653
  s(:gvasgn, :$var, s(:int, 10)),
@@ -723,9 +713,9 @@ class TestParser < MiniTest::Unit::TestCase
723
713
 
724
714
  # Constants
725
715
 
726
- def test_cdecl_toplevel
716
+ def test_casgn_toplevel
727
717
  assert_parses(
728
- s(:cdecl, s(:cbase), :Foo, s(:int, 10)),
718
+ s(:casgn, s(:cbase), :Foo, s(:int, 10)),
729
719
  %q{::Foo = 10},
730
720
  %q{ ~~~ name
731
721
  | ^ operator
@@ -734,9 +724,9 @@ class TestParser < MiniTest::Unit::TestCase
734
724
  })
735
725
  end
736
726
 
737
- def test_cdecl_scoped
727
+ def test_casgn_scoped
738
728
  assert_parses(
739
- s(:cdecl, s(:const, nil, :Bar), :Foo, s(:int, 10)),
729
+ s(:casgn, s(:const, nil, :Bar), :Foo, s(:int, 10)),
740
730
  %q{Bar::Foo = 10},
741
731
  %q{ ~~~ name
742
732
  | ^ operator
@@ -745,9 +735,9 @@ class TestParser < MiniTest::Unit::TestCase
745
735
  })
746
736
  end
747
737
 
748
- def test_cdecl_unscoped
738
+ def test_casgn_unscoped
749
739
  assert_parses(
750
- s(:cdecl, nil, :Foo, s(:int, 10)),
740
+ s(:casgn, nil, :Foo, s(:int, 10)),
751
741
  %q{Foo = 10},
752
742
  %q{~~~ name
753
743
  | ^ operator
@@ -755,7 +745,7 @@ class TestParser < MiniTest::Unit::TestCase
755
745
  })
756
746
  end
757
747
 
758
- def test_cdecl_invalid
748
+ def test_casgn_invalid
759
749
  assert_diagnoses(
760
750
  [:error, :dynamic_const],
761
751
  %q{def f; Foo = 1; end},
@@ -809,7 +799,7 @@ class TestParser < MiniTest::Unit::TestCase
809
799
  def test_masgn_splat
810
800
  assert_parses(
811
801
  s(:masgn,
812
- s(:mlhs, s(:ivasgn, :@foo), s(:cvdecl, :@@bar)),
802
+ s(:mlhs, s(:ivasgn, :@foo), s(:cvasgn, :@@bar)),
813
803
  s(:array, s(:splat, s(:lvar, :foo)))),
814
804
  %q{@foo, @@bar = *foo},
815
805
  %q{ ^ operator (array.splat)
@@ -951,7 +941,7 @@ class TestParser < MiniTest::Unit::TestCase
951
941
  assert_parses(
952
942
  s(:masgn,
953
943
  s(:mlhs,
954
- s(:cdecl, s(:self), :A),
944
+ s(:casgn, s(:self), :A),
955
945
  s(:lvasgn, :foo)),
956
946
  s(:lvar, :foo)),
957
947
  %q{self::A, foo = foo})
@@ -959,7 +949,7 @@ class TestParser < MiniTest::Unit::TestCase
959
949
  assert_parses(
960
950
  s(:masgn,
961
951
  s(:mlhs,
962
- s(:cdecl, s(:cbase), :A),
952
+ s(:casgn, s(:cbase), :A),
963
953
  s(:lvasgn, :foo)),
964
954
  s(:lvar, :foo)),
965
955
  %q{::A, foo = foo})
@@ -1038,7 +1028,7 @@ class TestParser < MiniTest::Unit::TestCase
1038
1028
  |~~~~~~~ expression})
1039
1029
 
1040
1030
  assert_parses(
1041
- s(:op_asgn, s(:cvdecl, :@@var), :|, s(:int, 10)),
1031
+ s(:op_asgn, s(:cvasgn, :@@var), :|, s(:int, 10)),
1042
1032
  %q{@@var |= 10})
1043
1033
 
1044
1034
  assert_parses(
@@ -1065,13 +1055,13 @@ class TestParser < MiniTest::Unit::TestCase
1065
1055
  def test_const_op_asgn
1066
1056
  assert_parses(
1067
1057
  s(:op_asgn,
1068
- s(:cdecl, nil, :A), :+,
1058
+ s(:casgn, nil, :A), :+,
1069
1059
  s(:int, 1)),
1070
1060
  %q{A += 1})
1071
1061
 
1072
1062
  assert_parses(
1073
1063
  s(:op_asgn,
1074
- s(:cdecl, s(:cbase), :A), :+,
1064
+ s(:casgn, s(:cbase), :A), :+,
1075
1065
  s(:int, 1)),
1076
1066
  %q{::A += 1},
1077
1067
  %q{},
@@ -1079,7 +1069,7 @@ class TestParser < MiniTest::Unit::TestCase
1079
1069
 
1080
1070
  assert_parses(
1081
1071
  s(:op_asgn,
1082
- s(:cdecl, s(:const, nil, :B), :A), :+,
1072
+ s(:casgn, s(:const, nil, :B), :A), :+,
1083
1073
  s(:int, 1)),
1084
1074
  %q{B::A += 1},
1085
1075
  %q{},
@@ -1800,6 +1790,12 @@ class TestParser < MiniTest::Unit::TestCase
1800
1790
  s(:kwarg, :foo)),
1801
1791
  %Q{foo:\n},
1802
1792
  ALL_VERSIONS - %w(1.8 1.9 2.0))
1793
+
1794
+ assert_parses_args(
1795
+ s(:args,
1796
+ s(:kwoptarg, :foo, s(:int, -1))),
1797
+ %Q{foo: -1\n},
1798
+ ALL_VERSIONS - %w(1.8 1.9 2.0))
1803
1799
  end
1804
1800
 
1805
1801
  def assert_parses_margs(ast, code, versions=ALL_VERSIONS - %w(1.8))
@@ -2770,7 +2766,7 @@ class TestParser < MiniTest::Unit::TestCase
2770
2766
  |~~~~~~~~~ expression})
2771
2767
 
2772
2768
  assert_parses(
2773
- s(:cdecl, s(:lvar, :foo), :A, s(:int, 1)),
2769
+ s(:casgn, s(:lvar, :foo), :A, s(:int, 1)),
2774
2770
  %q{foo::A = 1},
2775
2771
  %q{ ~ name
2776
2772
  | ^^ double_colon
@@ -4139,25 +4135,6 @@ class TestParser < MiniTest::Unit::TestCase
4139
4135
  # Miscellanea
4140
4136
  #
4141
4137
 
4142
- def test_crlf_line_endings
4143
- with_versions(nil, ALL_VERSIONS) do |_ver, parser|
4144
- source_file = Parser::Source::Buffer.new('(comments)')
4145
- source_file.source = "\r\nfoo"
4146
-
4147
- range = lambda do |from, to|
4148
- Parser::Source::Range.new(source_file, from, to)
4149
- end
4150
-
4151
- ast = parser.parse(source_file)
4152
-
4153
- assert_equal s(:lvar, :foo),
4154
- ast
4155
-
4156
- assert_equal range.call(2, 5),
4157
- ast.src.expression
4158
- end
4159
- end
4160
-
4161
4138
  def test_begin_cmdarg
4162
4139
  assert_parses(
4163
4140
  s(:send, nil, :p,
@@ -4197,6 +4174,26 @@ class TestParser < MiniTest::Unit::TestCase
4197
4174
  %q{~~ location})
4198
4175
  end
4199
4176
 
4177
+ def test_unterminated_embedded_doc
4178
+ assert_diagnoses(
4179
+ [:fatal, :embedded_document],
4180
+ %Q{=begin\nfoo\nend},
4181
+ %q{~~~~~~ location})
4182
+
4183
+ assert_diagnoses(
4184
+ [:fatal, :embedded_document],
4185
+ %Q{=begin\nfoo\nend\n},
4186
+ %q{~~~~~~ location})
4187
+ end
4188
+
4189
+ def test_codepoint_too_large
4190
+ assert_diagnoses(
4191
+ [:error, :unicode_point_too_large],
4192
+ %q{"\u{120 120000}"},
4193
+ %q{ ~~~~~~ location},
4194
+ ALL_VERSIONS - %w(1.8))
4195
+ end
4196
+
4200
4197
  def test_on_error
4201
4198
  assert_diagnoses(
4202
4199
  [:error, :unexpected_token, { :token => 'tIDENTIFIER' }],
@@ -4204,6 +4201,47 @@ class TestParser < MiniTest::Unit::TestCase
4204
4201
  %q{ ~~~ location})
4205
4202
  end
4206
4203
 
4204
+ #
4205
+ # Token and comment extraction
4206
+ #
4207
+
4208
+ def test_comments
4209
+ with_versions(ALL_VERSIONS) do |_ver, parser|
4210
+ source_file = Parser::Source::Buffer.new('(comments)')
4211
+ source_file.source = "1 + # foo\n 2"
4212
+
4213
+ range = lambda do |from, to|
4214
+ Parser::Source::Range.new(source_file, from, to)
4215
+ end
4216
+
4217
+ _ast, comments = parser.parse_with_comments(source_file)
4218
+
4219
+ assert_equal [
4220
+ Parser::Source::Comment.new(range.call(4, 9))
4221
+ ], comments
4222
+ end
4223
+ end
4224
+
4225
+ def test_tokenize
4226
+ with_versions(ALL_VERSIONS) do |_ver, parser|
4227
+ source_file = Parser::Source::Buffer.new('(tokenize)')
4228
+ source_file.source = "1 + # foo\n 2"
4229
+
4230
+ range = lambda do |from, to|
4231
+ Parser::Source::Range.new(source_file, from, to)
4232
+ end
4233
+
4234
+ _ast, _comments, tokens = parser.tokenize(source_file)
4235
+
4236
+ assert_equal [
4237
+ [:tINTEGER, [ 1, range.call(0, 1) ]],
4238
+ [:tPLUS, [ '+', range.call(2, 3) ]],
4239
+ [:tCOMMENT, [ '# foo', range.call(4, 9) ]],
4240
+ [:tINTEGER, [ 2, range.call(11, 12) ]],
4241
+ ], tokens
4242
+ end
4243
+ end
4244
+
4207
4245
  #
4208
4246
  # Bug-specific tests
4209
4247
  #