parser 1.4.2 → 2.0.0.beta1
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.
- 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
|
#
|