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.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -0
- data/CHANGELOG.md +167 -0
- data/CONTRIBUTING.md +10 -0
- data/Gemfile +4 -0
- data/README.md +56 -6
- data/Rakefile +66 -3
- data/doc/AST_FORMAT.md +3 -16
- data/lib/parser.rb +3 -0
- data/lib/parser/ast/node.rb +4 -4
- data/lib/parser/ast/processor.rb +1 -2
- data/lib/parser/base.rb +30 -2
- data/lib/parser/builders/default.rb +90 -70
- data/lib/parser/lexer.rl +98 -73
- data/lib/parser/lexer/explanation.rb +2 -11
- data/lib/parser/rewriter.rb +1 -2
- data/lib/parser/ruby18.y +2 -11
- data/lib/parser/ruby19.y +3 -14
- data/lib/parser/ruby20.y +3 -14
- data/lib/parser/ruby21.y +3 -14
- data/lib/parser/runner/ruby_parse.rb +1 -1
- data/lib/parser/source/buffer.rb +8 -18
- data/lib/parser/source/comment.rb +46 -0
- data/lib/parser/source/comment/associator.rb +70 -0
- data/lib/parser/source/map.rb +4 -0
- data/lib/parser/source/range.rb +2 -2
- data/lib/parser/version.rb +1 -1
- data/parser.gemspec +4 -3
- data/test/parse_helper.rb +6 -6
- data/test/test_lexer.rb +263 -15
- data/test/test_parser.rb +86 -48
- data/test/test_source_comment.rb +34 -0
- data/test/test_source_comment_associator.rb +48 -0
- data/test/test_source_range.rb +22 -16
- metadata +13 -5
- data/.jrubyrc +0 -1
data/test/test_lexer.rb
CHANGED
@@ -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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
485
|
-
|
486
|
-
# @lex.cond.push true
|
493
|
+
def test_do_cond
|
494
|
+
@lex.cond.push true
|
487
495
|
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
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",
|
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, "\"",
|
data/test/test_parser.rb
CHANGED
@@ -434,7 +434,8 @@ class TestParser < MiniTest::Unit::TestCase
|
|
434
434
|
%q[{ foo: 2 }],
|
435
435
|
%q{^ begin
|
436
436
|
| ^ end
|
437
|
-
|
|
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
|
641
|
+
def test_cvasgn
|
641
642
|
assert_parses(
|
642
|
-
s(:
|
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
|
716
|
+
def test_casgn_toplevel
|
727
717
|
assert_parses(
|
728
|
-
s(:
|
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
|
727
|
+
def test_casgn_scoped
|
738
728
|
assert_parses(
|
739
|
-
s(:
|
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
|
738
|
+
def test_casgn_unscoped
|
749
739
|
assert_parses(
|
750
|
-
s(:
|
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
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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(:
|
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
|
#
|