parser 2.3.0.2 → 2.3.0.3

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.
@@ -1,3 +1,3 @@
1
1
  module Parser
2
- VERSION = '2.3.0.2'
2
+ VERSION = '2.3.0.3'
3
3
  end
@@ -73,41 +73,51 @@ module ParseHelper
73
73
  # ~~~
74
74
  def assert_parses(ast, code, source_maps='', versions=ALL_VERSIONS)
75
75
  with_versions(versions) do |version, parser|
76
- source_file = Parser::Source::Buffer.new('(assert_parses)')
77
- source_file.source = code
76
+ try_parsing(ast, code, parser, source_maps, version)
77
+ end
78
78
 
79
- begin
80
- parsed_ast = parser.parse(source_file)
81
- rescue => exc
82
- backtrace = exc.backtrace
83
- Exception.instance_method(:initialize).bind(exc).
84
- call("(#{version}) #{exc.message}")
85
- exc.set_backtrace(backtrace)
86
- raise
87
- end
79
+ # Also try parsing with lexer set to use UTF-32LE internally
80
+ with_versions(versions) do |version, parser|
81
+ parser.instance_eval { @lexer.force_utf32 = true }
82
+ try_parsing(ast, code, parser, source_maps, version)
83
+ end
84
+ end
88
85
 
89
- assert_equal ast, parsed_ast,
90
- "(#{version}) AST equality"
86
+ def try_parsing(ast, code, parser, source_maps, version)
87
+ source_file = Parser::Source::Buffer.new('(assert_parses)')
88
+ source_file.source = code
89
+
90
+ begin
91
+ parsed_ast = parser.parse(source_file)
92
+ rescue => exc
93
+ backtrace = exc.backtrace
94
+ Exception.instance_method(:initialize).bind(exc).
95
+ call("(#{version}) #{exc.message}")
96
+ exc.set_backtrace(backtrace)
97
+ raise
98
+ end
91
99
 
92
- parse_source_map_descriptions(source_maps) \
93
- do |begin_pos, end_pos, map_field, ast_path, line|
100
+ assert_equal ast, parsed_ast,
101
+ "(#{version}) AST equality"
94
102
 
95
- astlet = traverse_ast(parsed_ast, ast_path)
103
+ parse_source_map_descriptions(source_maps) \
104
+ do |begin_pos, end_pos, map_field, ast_path, line|
96
105
 
97
- if astlet.nil?
98
- # This is a testsuite bug.
99
- raise "No entity with AST path #{ast_path} in #{parsed_ast.inspect}"
100
- end
106
+ astlet = traverse_ast(parsed_ast, ast_path)
101
107
 
102
- assert astlet.frozen?
108
+ if astlet.nil?
109
+ # This is a testsuite bug.
110
+ raise "No entity with AST path #{ast_path} in #{parsed_ast.inspect}"
111
+ end
103
112
 
104
- assert astlet.location.respond_to?(map_field),
105
- "(#{version}) #{astlet.location.inspect}.respond_to?(#{map_field.inspect}) for:\n#{parsed_ast.inspect}"
113
+ assert astlet.frozen?
106
114
 
107
- range = astlet.location.send(map_field)
115
+ assert astlet.location.respond_to?(map_field),
116
+ "(#{version}) #{astlet.location.inspect}.respond_to?(#{map_field.inspect}) for:\n#{parsed_ast.inspect}"
108
117
 
109
- assert_source_range(begin_pos, end_pos, range, version, line.inspect)
110
- end
118
+ range = astlet.location.send(map_field)
119
+
120
+ assert_source_range(begin_pos, end_pos, range, version, line.inspect)
111
121
  end
112
122
  end
113
123
 
@@ -70,8 +70,11 @@ class TestLexer < Minitest::Test
70
70
  assert_equal :fatal, err.diagnostic.level
71
71
  end
72
72
 
73
- def assert_lex_fname(name, type)
74
- assert_scanned("def #{name} ", :kDEF, 'def', type, name)
73
+ def assert_lex_fname(name, type, range)
74
+ begin_pos, end_pos = range
75
+ assert_scanned("def #{name} ",
76
+ :kDEF, 'def', [0, 3],
77
+ type, name, [begin_pos + 4, end_pos + 4])
75
78
 
76
79
  assert_equal :expr_endfn, @lex.state
77
80
  end
@@ -84,11 +87,13 @@ class TestLexer < Minitest::Test
84
87
  @lex.source_buffer = source_buffer
85
88
 
86
89
  until args.empty? do
87
- token, value = args.shift(2)
90
+ token, value, (begin_pos, end_pos) = args.shift(3)
88
91
 
89
- lex_token, (lex_value, *) = @lex.advance
92
+ lex_token, (lex_value, lex_range) = @lex.advance
90
93
  assert lex_token, 'no more tokens'
91
94
  assert_operator [lex_token, lex_value], :eql?, [token, value], input
95
+ assert_equal begin_pos, lex_range.begin_pos
96
+ assert_equal end_pos, lex_range.end_pos
92
97
  end
93
98
 
94
99
  lex_token, (lex_value, *) = @lex.advance
@@ -172,151 +177,151 @@ class TestLexer < Minitest::Test
172
177
 
173
178
  def test_ambiguous_uminus
174
179
  assert_scanned("m -3",
175
- :tIDENTIFIER, "m",
176
- :tUMINUS_NUM, "-",
177
- :tINTEGER, 3)
180
+ :tIDENTIFIER, "m", [0, 1],
181
+ :tUMINUS_NUM, "-", [2, 3],
182
+ :tINTEGER, 3, [3, 4])
178
183
  end
179
184
 
180
185
  def test_ambiguous_uplus
181
186
  assert_scanned("m +3",
182
- :tIDENTIFIER, "m",
183
- :tINTEGER, 3)
187
+ :tIDENTIFIER, "m", [0, 1],
188
+ :tINTEGER, 3, [3, 4])
184
189
  end
185
190
 
186
191
  def test_and
187
- assert_scanned "&", :tAMPER, "&"
192
+ assert_scanned "&", :tAMPER, "&", [0, 1]
188
193
  end
189
194
 
190
195
  def test_and2
191
196
  @lex.state = :expr_end
192
197
 
193
- assert_scanned "&&", :tANDOP, "&&"
198
+ assert_scanned "&&", :tANDOP, "&&", [0, 2]
194
199
  end
195
200
 
196
201
  def test_and2_equals
197
202
  @lex.state = :expr_end
198
203
 
199
- assert_scanned "&&=", :tOP_ASGN, "&&"
204
+ assert_scanned "&&=", :tOP_ASGN, "&&", [0, 3]
200
205
  end
201
206
 
202
207
  def test_and_arg
203
208
  @lex.state = :expr_arg
204
209
 
205
210
  assert_scanned(" &y",
206
- :tAMPER, "&",
207
- :tIDENTIFIER, "y")
211
+ :tAMPER, "&", [1, 2],
212
+ :tIDENTIFIER, "y", [2, 3])
208
213
  end
209
214
 
210
215
  def test_and_equals
211
216
  @lex.state = :expr_end
212
217
 
213
- assert_scanned "&=", :tOP_ASGN, "&"
218
+ assert_scanned "&=", :tOP_ASGN, "&", [0, 2]
214
219
  end
215
220
 
216
221
  def test_and_expr
217
222
  @lex.state = :expr_arg
218
223
 
219
224
  assert_scanned("x & y",
220
- :tIDENTIFIER, "x",
221
- :tAMPER2, "&",
222
- :tIDENTIFIER, "y")
225
+ :tIDENTIFIER, "x", [0, 1],
226
+ :tAMPER2, "&", [2, 3],
227
+ :tIDENTIFIER, "y", [4, 5])
223
228
  end
224
229
 
225
230
  def test_and_meth
226
- assert_lex_fname "&", :tAMPER2
231
+ assert_lex_fname "&", :tAMPER2, [0, 1]
227
232
  end
228
233
 
229
234
  def test_and_dot
230
235
  @lex.state = :expr_cmdarg
231
236
 
232
- assert_scanned "&.", :tANDDOT, "&."
237
+ assert_scanned "&.", :tANDDOT, "&.", [0, 2]
233
238
  end
234
239
 
235
240
  def test_assoc
236
- assert_scanned "=>", :tASSOC, "=>"
241
+ assert_scanned "=>", :tASSOC, "=>", [0, 2]
237
242
  end
238
243
 
239
244
  def test_label__18
240
245
  assert_scanned("{a:b",
241
- :tLBRACE, "{",
242
- :tIDENTIFIER, "a",
243
- :tSYMBOL, "b")
246
+ :tLBRACE, "{", [0, 1],
247
+ :tIDENTIFIER, "a", [1, 2],
248
+ :tSYMBOL, "b", [2, 4])
244
249
  end
245
250
 
246
251
  def test_label_in_params__18
247
252
  assert_scanned("foo(a:b",
248
- :tIDENTIFIER, "foo",
249
- :tLPAREN2, "(",
250
- :tIDENTIFIER, "a",
251
- :tSYMBOL, "b")
253
+ :tIDENTIFIER, "foo", [0, 3],
254
+ :tLPAREN2, "(", [3, 4],
255
+ :tIDENTIFIER, "a", [4, 5],
256
+ :tSYMBOL, "b", [5, 7])
252
257
  end
253
258
 
254
259
  def test_label__19
255
260
  setup_lexer 19
256
261
 
257
262
  assert_scanned("{a:b",
258
- :tLBRACE, "{",
259
- :tLABEL, "a",
260
- :tIDENTIFIER, "b")
263
+ :tLBRACE, "{", [0, 1],
264
+ :tLABEL, "a", [1, 3],
265
+ :tIDENTIFIER, "b", [3, 4])
261
266
  end
262
267
 
263
268
  def test_label_in_params__19
264
269
  setup_lexer 19
265
270
 
266
271
  assert_scanned("foo(a:b",
267
- :tIDENTIFIER, "foo",
268
- :tLPAREN2, "(",
269
- :tLABEL, "a",
270
- :tIDENTIFIER, "b")
272
+ :tIDENTIFIER, "foo", [0, 3],
273
+ :tLPAREN2, "(", [3, 4],
274
+ :tLABEL, "a", [4, 6],
275
+ :tIDENTIFIER, "b", [6, 7])
271
276
  end
272
277
 
273
278
  def test_label_fid__19
274
279
  setup_lexer 19
275
280
 
276
281
  assert_scanned("{a?:true",
277
- :tLBRACE, '{',
278
- :tLABEL, 'a?',
279
- :kTRUE, 'true')
282
+ :tLBRACE, '{', [0, 1],
283
+ :tLABEL, 'a?', [1, 4],
284
+ :kTRUE, 'true', [4, 8])
280
285
  end
281
286
 
282
287
  def test_label__22
283
288
  setup_lexer 22
284
289
 
285
290
  assert_scanned("{'a':",
286
- :tLBRACE, '{',
287
- :tSTRING_BEG, "'",
288
- :tSTRING_CONTENT, 'a',
289
- :tLABEL_END, "'")
291
+ :tLBRACE, '{', [0, 1],
292
+ :tSTRING_BEG, "'", [1, 2],
293
+ :tSTRING_CONTENT, 'a', [2, 3],
294
+ :tLABEL_END, "'", [3, 5])
290
295
  end
291
296
 
292
297
  def test_label_nested__22
293
298
  setup_lexer 22
294
299
 
295
300
  assert_scanned("{'a\":':",
296
- :tLBRACE, '{',
297
- :tSTRING_BEG, "'",
298
- :tSTRING_CONTENT, 'a":',
299
- :tLABEL_END, "'")
301
+ :tLBRACE, '{', [0, 1],
302
+ :tSTRING_BEG, "'", [1, 2],
303
+ :tSTRING_CONTENT, 'a":', [2, 5],
304
+ :tLABEL_END, "'", [5, 7])
300
305
  end
301
306
 
302
307
  def test_label_colon2__22
303
308
  setup_lexer 22
304
309
 
305
310
  assert_scanned("{'a'::",
306
- :tLBRACE, '{',
307
- :tSTRING, "a",
308
- :tCOLON2, '::')
311
+ :tLBRACE, '{', [0, 1],
312
+ :tSTRING, "a", [1, 4],
313
+ :tCOLON2, '::', [4, 6])
309
314
  end
310
315
 
311
316
  def test_pct_string_colon__22
312
317
  setup_lexer 22
313
318
 
314
319
  assert_scanned("{%'a':",
315
- :tLBRACE, '{',
316
- :tSTRING_BEG, "%'",
317
- :tSTRING_CONTENT, 'a',
318
- :tSTRING_END, "'",
319
- :tCOLON, ':')
320
+ :tLBRACE, '{', [0, 1],
321
+ :tSTRING_BEG, "%'", [1, 3],
322
+ :tSTRING_CONTENT, 'a', [3, 4],
323
+ :tSTRING_END, "'", [4, 5],
324
+ :tCOLON, ':', [5, 6])
320
325
  end
321
326
 
322
327
  def test_command_start__19
@@ -328,9 +333,9 @@ class TestLexer < Minitest::Test
328
333
 
329
334
  @lex.reset
330
335
  assert_scanned("#{keyword} a:b",
331
- token, keyword,
332
- :tIDENTIFIER, "a",
333
- :tSYMBOL, "b")
336
+ token, keyword, [0, keyword.length],
337
+ :tIDENTIFIER, "a", [keyword.length + 1, keyword.length + 2],
338
+ :tSYMBOL, "b", [keyword.length + 2, keyword.length + 4])
334
339
  end
335
340
  end
336
341
 
@@ -342,44 +347,44 @@ class TestLexer < Minitest::Test
342
347
 
343
348
  @lex.state = :expr_end
344
349
  assert_scanned("#{keyword} a:b",
345
- token, keyword,
346
- :tLABEL, "a",
347
- :tIDENTIFIER, "b")
350
+ token, keyword, [0, keyword.length],
351
+ :tLABEL, "a", [keyword.length + 1, keyword.length + 3],
352
+ :tIDENTIFIER, "b", [keyword.length + 3, keyword.length + 4])
348
353
  end
349
354
  end
350
355
 
351
356
  def test_back_ref
352
357
  assert_scanned("[$&, $`, $', $+]",
353
- :tLBRACK, "[",
354
- :tBACK_REF, "$&", :tCOMMA, ",",
355
- :tBACK_REF, "$`", :tCOMMA, ",",
356
- :tBACK_REF, "$'", :tCOMMA, ",",
357
- :tBACK_REF, "$+",
358
- :tRBRACK, "]")
358
+ :tLBRACK, "[", [0, 1],
359
+ :tBACK_REF, "$&", [1, 3], :tCOMMA, ",", [3, 4],
360
+ :tBACK_REF, "$`", [5, 7], :tCOMMA, ",", [7, 8],
361
+ :tBACK_REF, "$'", [9, 11], :tCOMMA, ",", [11, 12],
362
+ :tBACK_REF, "$+", [13, 15],
363
+ :tRBRACK, "]", [15, 16])
359
364
  end
360
365
 
361
366
  def test_backslash
362
367
  assert_scanned("1 \\\n+ 2",
363
- :tINTEGER, 1,
364
- :tPLUS, "+",
365
- :tINTEGER, 2)
368
+ :tINTEGER, 1, [0, 1],
369
+ :tPLUS, "+", [4, 5],
370
+ :tINTEGER, 2, [6, 7])
366
371
  end
367
372
 
368
373
  def test_backslash_bad
369
374
  refute_scanned("1 \\ + 2",
370
- :tINTEGER, 1)
375
+ :tINTEGER, 1, [0, 1])
371
376
  end
372
377
 
373
378
  def test_backtick
374
379
  assert_scanned("`ls`",
375
- :tXSTRING_BEG, "`",
376
- :tSTRING_CONTENT, "ls",
377
- :tSTRING_END, "`")
380
+ :tXSTRING_BEG, "`", [0, 1],
381
+ :tSTRING_CONTENT, "ls", [1, 3],
382
+ :tSTRING_END, "`", [3, 4])
378
383
  end
379
384
 
380
385
  def test_backtick_cmdarg
381
386
  @lex.state = :expr_dot
382
- assert_scanned("\n`", :tBACK_REF2, "`") # \n ensures expr_cmd
387
+ assert_scanned("\n`", :tBACK_REF2, "`", [1, 2]) # \n ensures expr_cmd
383
388
 
384
389
  assert_equal :expr_arg, @lex.state
385
390
  end
@@ -387,17 +392,17 @@ class TestLexer < Minitest::Test
387
392
  def test_backtick_dot
388
393
  @lex.state = :expr_dot
389
394
  assert_scanned("a.`(3)",
390
- :tIDENTIFIER, "a",
391
- :tDOT, ".",
392
- :tBACK_REF2, "`",
393
- :tLPAREN2, "(",
394
- :tINTEGER, 3,
395
- :tRPAREN, ")")
395
+ :tIDENTIFIER, "a", [0, 1],
396
+ :tDOT, ".", [1, 2],
397
+ :tBACK_REF2, "`", [2, 3],
398
+ :tLPAREN2, "(", [3, 4],
399
+ :tINTEGER, 3, [4, 5],
400
+ :tRPAREN, ")", [5, 6])
396
401
  end
397
402
 
398
403
  def test_backtick_method
399
404
  @lex.state = :expr_fname
400
- assert_scanned("`", :tBACK_REF2, "`")
405
+ assert_scanned("`", :tBACK_REF2, "`", [0, 1])
401
406
  assert_equal :expr_endfn, @lex.state
402
407
  end
403
408
 
@@ -406,64 +411,64 @@ class TestLexer < Minitest::Test
406
411
  end
407
412
 
408
413
  def test_bang
409
- assert_scanned "!", :tBANG, "!"
414
+ assert_scanned "!", :tBANG, "!", [0, 1]
410
415
  end
411
416
 
412
417
  def test_bang_equals
413
- assert_scanned "!=", :tNEQ, "!="
418
+ assert_scanned "!=", :tNEQ, "!=", [0, 2]
414
419
  end
415
420
 
416
421
  def test_bang_tilde
417
- assert_scanned "!~", :tNMATCH, "!~"
422
+ assert_scanned "!~", :tNMATCH, "!~", [0, 2]
418
423
  end
419
424
 
420
425
  def test_def_ubang
421
426
  setup_lexer(20)
422
427
 
423
428
  @lex.state = :expr_fname
424
- assert_scanned '!@', :tBANG, '!@'
429
+ assert_scanned '!@', :tBANG, '!@', [0, 2]
425
430
  end
426
431
 
427
432
  def test_carat
428
- assert_scanned "^", :tCARET, "^"
433
+ assert_scanned "^", :tCARET, "^", [0, 1]
429
434
  end
430
435
 
431
436
  def test_carat_equals
432
- assert_scanned "^=", :tOP_ASGN, "^"
437
+ assert_scanned "^=", :tOP_ASGN, "^", [0, 2]
433
438
  end
434
439
 
435
440
  def test_colon2
436
441
  assert_scanned("A::B",
437
- :tCONSTANT, "A",
438
- :tCOLON2, "::",
439
- :tCONSTANT, "B")
442
+ :tCONSTANT, "A", [0, 1],
443
+ :tCOLON2, "::", [1, 3],
444
+ :tCONSTANT, "B", [3, 4])
440
445
 
441
446
  @lex.state = :expr_arg
442
447
  assert_scanned("::Array",
443
- :tCOLON2, "::",
444
- :tCONSTANT, "Array")
448
+ :tCOLON2, "::", [0, 2],
449
+ :tCONSTANT, "Array", [2, 7])
445
450
  end
446
451
 
447
452
  def test_colon3
448
453
  assert_scanned("::Array",
449
- :tCOLON3, "::",
450
- :tCONSTANT, "Array")
454
+ :tCOLON3, "::", [0, 2],
455
+ :tCONSTANT, "Array", [2, 7])
451
456
 
452
457
  @lex.state = :expr_arg
453
458
  assert_scanned(" ::Array",
454
- :tCOLON3, "::",
455
- :tCONSTANT, "Array")
459
+ :tCOLON3, "::", [1, 3],
460
+ :tCONSTANT, "Array", [3, 8])
456
461
  end
457
462
 
458
463
  def test_comma
459
- assert_scanned ",", :tCOMMA, ","
464
+ assert_scanned ",", :tCOMMA, ",", [0, 1]
460
465
  end
461
466
 
462
467
  def test_comment
463
468
  assert_scanned("1 # one\n# two\n2",
464
- :tINTEGER, 1,
465
- :tNL, nil,
466
- :tINTEGER, 2)
469
+ :tINTEGER, 1, [0, 1],
470
+ :tNL, nil, [7, 8],
471
+ :tINTEGER, 2, [14, 15])
467
472
 
468
473
  assert_equal 2, @lex.comments.length
469
474
  assert_equal '# one', @lex.comments[0].text
@@ -472,13 +477,13 @@ class TestLexer < Minitest::Test
472
477
 
473
478
  def test_comment_expr_beg
474
479
  assert_scanned("{#1\n}",
475
- :tLBRACE, "{",
476
- :tRCURLY, "}")
480
+ :tLBRACE, "{", [0, 1],
481
+ :tRCURLY, "}", [4, 5])
477
482
  end
478
483
 
479
484
  def test_comment_begin
480
485
  assert_scanned("=begin\nblah\nblah\n=end\n42",
481
- :tINTEGER, 42)
486
+ :tINTEGER, 42, [22, 24])
482
487
  assert_equal 1, @lex.comments.length
483
488
  assert_equal "=begin\nblah\nblah\n=end\n", @lex.comments[0].text
484
489
  end
@@ -489,14 +494,14 @@ class TestLexer < Minitest::Test
489
494
 
490
495
  def test_comment_begin_not_comment
491
496
  assert_scanned("beginfoo = 5\np x \\\n=beginfoo",
492
- :tIDENTIFIER, "beginfoo",
493
- :tEQL, "=",
494
- :tINTEGER, 5,
495
- :tNL, nil,
496
- :tIDENTIFIER, "p",
497
- :tIDENTIFIER, "x",
498
- :tEQL, "=",
499
- :tIDENTIFIER, "beginfoo")
497
+ :tIDENTIFIER, "beginfoo", [0, 8],
498
+ :tEQL, "=", [9, 10],
499
+ :tINTEGER, 5, [11, 12],
500
+ :tNL, nil, [12, 13],
501
+ :tIDENTIFIER, "p", [13, 14],
502
+ :tIDENTIFIER, "x", [15, 16],
503
+ :tEQL, "=", [19, 20],
504
+ :tIDENTIFIER, "beginfoo", [20, 28])
500
505
  end
501
506
 
502
507
  def test_comment_begin_space
@@ -519,17 +524,17 @@ class TestLexer < Minitest::Test
519
524
 
520
525
  def test_constant
521
526
  assert_scanned("ArgumentError",
522
- :tCONSTANT, "ArgumentError")
527
+ :tCONSTANT, "ArgumentError", [0, 13])
523
528
  end
524
529
 
525
530
  def test_constant_semi
526
531
  assert_scanned("ArgumentError;",
527
- :tCONSTANT, "ArgumentError",
528
- :tSEMI, ";")
532
+ :tCONSTANT, "ArgumentError", [0, 13],
533
+ :tSEMI, ";", [13, 14])
529
534
  end
530
535
 
531
536
  def test_cvar
532
- assert_scanned "@@blah", :tCVAR, "@@blah"
537
+ assert_scanned "@@blah", :tCVAR, "@@blah", [0, 6]
533
538
  end
534
539
 
535
540
  def test_cvar_bad
@@ -538,85 +543,85 @@ class TestLexer < Minitest::Test
538
543
 
539
544
  def test_div
540
545
  assert_scanned("a / 2",
541
- :tIDENTIFIER, "a",
542
- :tDIVIDE, "/",
543
- :tINTEGER, 2)
546
+ :tIDENTIFIER, "a", [0, 1],
547
+ :tDIVIDE, "/", [2, 3],
548
+ :tINTEGER, 2, [4, 5])
544
549
  end
545
550
 
546
551
  def test_div_equals
547
552
  assert_scanned("a /= 2",
548
- :tIDENTIFIER, "a",
549
- :tOP_ASGN, "/",
550
- :tINTEGER, 2)
553
+ :tIDENTIFIER, "a", [0, 1],
554
+ :tOP_ASGN, "/", [2, 4],
555
+ :tINTEGER, 2, [5, 6])
551
556
  end
552
557
 
553
558
  def test_do
554
559
  assert_scanned("x do 42 end",
555
- :tIDENTIFIER, "x",
556
- :kDO, "do",
557
- :tINTEGER, 42,
558
- :kEND, "end")
560
+ :tIDENTIFIER, "x", [0, 1],
561
+ :kDO, "do", [2, 4],
562
+ :tINTEGER, 42, [5, 7],
563
+ :kEND, "end", [8, 11])
559
564
  end
560
565
 
561
566
  def test_do_cond
562
567
  @lex.cond.push(true)
563
568
 
564
569
  assert_scanned("x do 42 end",
565
- :tIDENTIFIER, "x",
566
- :kDO_COND, "do",
567
- :tINTEGER, 42,
568
- :kEND, "end")
570
+ :tIDENTIFIER, "x", [0, 1],
571
+ :kDO_COND, "do", [2, 4],
572
+ :tINTEGER, 42, [5, 7],
573
+ :kEND, "end", [8, 11])
569
574
  end
570
575
 
571
576
  def test_do_block
572
577
  @lex.state = :expr_endarg
573
578
 
574
579
  assert_scanned("do 42 end",
575
- :kDO_BLOCK, "do",
576
- :tINTEGER, 42,
577
- :kEND, "end")
580
+ :kDO_BLOCK, "do", [0, 2],
581
+ :tINTEGER, 42, [3, 5],
582
+ :kEND, "end", [6, 9])
578
583
  end
579
584
 
580
585
  def test_do_cond
581
586
  @lex.cond.push true
582
587
 
583
588
  assert_scanned("x do 42 end",
584
- :tIDENTIFIER, "x",
585
- :kDO_COND, "do",
586
- :tINTEGER, 42,
587
- :kEND, "end")
589
+ :tIDENTIFIER, "x", [0, 1],
590
+ :kDO_COND, "do", [2, 4],
591
+ :tINTEGER, 42, [5, 7],
592
+ :kEND, "end", [8, 11])
588
593
  end
589
594
 
590
595
  def test_dot
591
- assert_scanned ".", :tDOT, "."
596
+ assert_scanned ".", :tDOT, ".", [0, 1]
592
597
  end
593
598
 
594
599
  def test_dot2
595
- assert_scanned "..", :tDOT2, ".."
600
+ assert_scanned "..", :tDOT2, "..", [0, 2]
596
601
  end
597
602
 
598
603
  def test_dot3
599
- assert_scanned "...", :tDOT3, "..."
604
+ assert_scanned "...", :tDOT3, "...", [0, 3]
600
605
  end
601
606
 
602
607
  def test_equals
603
- assert_scanned "=", :tEQL, "="
608
+ assert_scanned "=", :tEQL, "=", [0, 1]
604
609
  end
605
610
 
606
611
  def test_equals2
607
- assert_scanned "==", :tEQ, "=="
612
+ assert_scanned "==", :tEQ, "==", [0, 2]
608
613
  end
609
614
 
610
615
  def test_equals3
611
- assert_scanned "===", :tEQQ, "==="
616
+ assert_scanned "===", :tEQQ, "===", [0, 3]
612
617
  end
613
618
 
614
619
  def test_equals_tilde
615
- assert_scanned "=~", :tMATCH, "=~"
620
+ assert_scanned "=~", :tMATCH, "=~", [0, 2]
616
621
  end
617
622
 
618
623
  def test_float
619
- assert_scanned "1.0", :tFLOAT, 1.0
624
+ assert_scanned "1.0", :tFLOAT, 1.0, [0, 3]
620
625
  end
621
626
 
622
627
  def test_float_bad_no_underscores
@@ -633,33 +638,33 @@ class TestLexer < Minitest::Test
633
638
 
634
639
  def test_float_call
635
640
  assert_scanned("1.0.to_s",
636
- :tFLOAT, 1.0,
637
- :tDOT, ".",
638
- :tIDENTIFIER, "to_s")
641
+ :tFLOAT, 1.0, [0, 3],
642
+ :tDOT, ".", [3, 4],
643
+ :tIDENTIFIER, "to_s", [4, 8])
639
644
  end
640
645
 
641
646
  def test_float_dot_E
642
- assert_scanned "1.0E10", :tFLOAT, 1.0e10
647
+ assert_scanned "1.0E10", :tFLOAT, 1.0e10, [0, 6]
643
648
  end
644
649
 
645
650
  def test_float_dot_E_neg
646
651
  assert_scanned("-1.0E10",
647
- :tUMINUS_NUM, "-",
648
- :tFLOAT, 1.0e10)
652
+ :tUMINUS_NUM, "-", [0, 1],
653
+ :tFLOAT, 1.0e10, [1, 7])
649
654
  end
650
655
 
651
656
  def test_float_dot_e
652
- assert_scanned "1.0e10", :tFLOAT, 1.0e10
657
+ assert_scanned "1.0e10", :tFLOAT, 1.0e10, [0, 6]
653
658
  end
654
659
 
655
660
  def test_float_dot_e_neg
656
661
  assert_scanned("-1.0e10",
657
- :tUMINUS_NUM, "-",
658
- :tFLOAT, 1.0e10)
662
+ :tUMINUS_NUM, "-", [0, 1],
663
+ :tFLOAT, 1.0e10, [1, 7])
659
664
  end
660
665
 
661
666
  def test_float_e
662
- assert_scanned "1e10", :tFLOAT, 1e10
667
+ assert_scanned "1e10", :tFLOAT, 1e10, [0, 4]
663
668
  end
664
669
 
665
670
  def test_float_e_bad_trailing_underscore
@@ -667,33 +672,33 @@ class TestLexer < Minitest::Test
667
672
  end
668
673
 
669
674
  def test_float_e_minus
670
- assert_scanned "1e-10", :tFLOAT, 1e-10
675
+ assert_scanned "1e-10", :tFLOAT, 1e-10, [0, 5]
671
676
  end
672
677
 
673
678
  def test_float_e_neg
674
679
  assert_scanned("-1e10",
675
- :tUMINUS_NUM, "-",
676
- :tFLOAT, 1e10)
680
+ :tUMINUS_NUM, "-", [0, 1],
681
+ :tFLOAT, 1e10, [1, 5])
677
682
  end
678
683
 
679
684
  def test_float_e_neg_minus
680
685
  assert_scanned("-1e-10",
681
- :tUMINUS_NUM, "-",
682
- :tFLOAT, 1e-10)
686
+ :tUMINUS_NUM, "-", [0, 1],
687
+ :tFLOAT, 1e-10, [1, 6])
683
688
  end
684
689
 
685
690
  def test_float_e_neg_plus
686
691
  assert_scanned("-1e+10",
687
- :tUMINUS_NUM, "-",
688
- :tFLOAT, 1e10)
692
+ :tUMINUS_NUM, "-", [0, 1],
693
+ :tFLOAT, 1e10, [1, 6])
689
694
  end
690
695
 
691
696
  def test_float_e_plus
692
- assert_scanned "1e+10", :tFLOAT, 1e10
697
+ assert_scanned "1e+10", :tFLOAT, 1e10, [0, 5]
693
698
  end
694
699
 
695
700
  def test_float_e_zero
696
- assert_scanned "0e0", :tFLOAT, 0e0
701
+ assert_scanned "0e0", :tFLOAT, 0e0, [0, 3]
697
702
  end
698
703
 
699
704
  def test_float_e_nothing
@@ -707,32 +712,32 @@ class TestLexer < Minitest::Test
707
712
  setup_lexer 21
708
713
 
709
714
  assert_scanned("1end",
710
- :tINTEGER, 1,
711
- :kEND, 'end')
715
+ :tINTEGER, 1, [0, 1],
716
+ :kEND, 'end', [1, 4])
712
717
  assert_scanned("1.1end",
713
- :tFLOAT, 1.1,
714
- :kEND, 'end')
718
+ :tFLOAT, 1.1, [0, 3],
719
+ :kEND, 'end', [3, 6])
715
720
  end
716
721
 
717
722
  def test_float_neg
718
723
  assert_scanned("-1.0",
719
- :tUMINUS_NUM, "-",
720
- :tFLOAT, 1.0)
724
+ :tUMINUS_NUM, "-", [0, 1],
725
+ :tFLOAT, 1.0, [1, 4])
721
726
  end
722
727
 
723
728
  def test_ge
724
729
  assert_scanned("a >= 2",
725
- :tIDENTIFIER, "a",
726
- :tGEQ, ">=",
727
- :tINTEGER, 2)
730
+ :tIDENTIFIER, "a", [0, 1],
731
+ :tGEQ, ">=", [2, 4],
732
+ :tINTEGER, 2, [5, 6])
728
733
  end
729
734
 
730
735
  def test_global
731
- assert_scanned("$blah", :tGVAR, "$blah")
736
+ assert_scanned("$blah", :tGVAR, "$blah", [0, 5])
732
737
  end
733
738
 
734
739
  def test_global_backref
735
- assert_scanned("$`", :tBACK_REF, "$`")
740
+ assert_scanned("$`", :tBACK_REF, "$`", [0, 2])
736
741
  end
737
742
 
738
743
  # This was removed in 2.1.
@@ -741,318 +746,327 @@ class TestLexer < Minitest::Test
741
746
  # end
742
747
 
743
748
  def test_global_dash_something
744
- assert_scanned("$-x", :tGVAR, "$-x")
749
+ assert_scanned("$-x", :tGVAR, "$-x", [0, 3])
745
750
  end
746
751
 
747
752
  def test_global_number
748
- assert_scanned("$10", :tNTH_REF, 10)
753
+ assert_scanned("$10", :tNTH_REF, 10, [0, 3])
749
754
  end
750
755
 
751
756
  def test_global_other
752
757
  assert_scanned("[$~, $*, $$, $?, $!, $@, $/, $\\, $;, $,, $., $=, $:, $<, $>, $\"]",
753
- :tLBRACK, "[",
754
- :tGVAR, "$~", :tCOMMA, ",",
755
- :tGVAR, "$*", :tCOMMA, ",",
756
- :tGVAR, "$$", :tCOMMA, ",",
757
- :tGVAR, "$\?", :tCOMMA, ",",
758
- :tGVAR, "$!", :tCOMMA, ",",
759
- :tGVAR, "$@", :tCOMMA, ",",
760
- :tGVAR, "$/", :tCOMMA, ",",
761
- :tGVAR, "$\\", :tCOMMA, ",",
762
- :tGVAR, "$;", :tCOMMA, ",",
763
- :tGVAR, "$,", :tCOMMA, ",",
764
- :tGVAR, "$.", :tCOMMA, ",",
765
- :tGVAR, "$=", :tCOMMA, ",",
766
- :tGVAR, "$:", :tCOMMA, ",",
767
- :tGVAR, "$<", :tCOMMA, ",",
768
- :tGVAR, "$>", :tCOMMA, ",",
769
- :tGVAR, "$\"",
770
- :tRBRACK, "]")
758
+ :tLBRACK, "[", [0, 1],
759
+ :tGVAR, "$~", [1, 3], :tCOMMA, ",", [3, 4],
760
+ :tGVAR, "$*", [5, 7], :tCOMMA, ",", [7, 8],
761
+ :tGVAR, "$$", [9, 11], :tCOMMA, ",", [11, 12],
762
+ :tGVAR, "$\?", [13, 15], :tCOMMA, ",", [15, 16],
763
+ :tGVAR, "$!", [17, 19], :tCOMMA, ",", [19, 20],
764
+ :tGVAR, "$@", [21, 23], :tCOMMA, ",", [23, 24],
765
+ :tGVAR, "$/", [25, 27], :tCOMMA, ",", [27, 28],
766
+ :tGVAR, "$\\", [29, 31], :tCOMMA, ",", [31, 32],
767
+ :tGVAR, "$;", [33, 35], :tCOMMA, ",", [35, 36],
768
+ :tGVAR, "$,", [37, 39], :tCOMMA, ",", [39, 40],
769
+ :tGVAR, "$.", [41, 43], :tCOMMA, ",", [43, 44],
770
+ :tGVAR, "$=", [45, 47], :tCOMMA, ",", [47, 48],
771
+ :tGVAR, "$:", [49, 51], :tCOMMA, ",", [51, 52],
772
+ :tGVAR, "$<", [53, 55], :tCOMMA, ",", [55, 56],
773
+ :tGVAR, "$>", [57, 59], :tCOMMA, ",", [59, 60],
774
+ :tGVAR, "$\"", [61, 63],
775
+ :tRBRACK, "]", [63, 64])
771
776
  end
772
777
 
773
778
  def test_global_underscore
774
779
  assert_scanned("$_",
775
- :tGVAR, "$_")
780
+ :tGVAR, "$_", [0, 2])
776
781
  end
777
782
 
778
- def test_global_wierd
783
+ def test_global_weird
779
784
  assert_scanned("$__blah",
780
- :tGVAR, "$__blah")
785
+ :tGVAR, "$__blah", [0, 7])
781
786
  end
782
787
 
783
788
  def test_global_zero
784
- assert_scanned("$0", :tGVAR, "$0")
789
+ assert_scanned("$0", :tGVAR, "$0", [0, 2])
785
790
  end
786
791
 
787
792
  def test_gt
788
793
  assert_scanned("a > 2",
789
- :tIDENTIFIER, "a",
790
- :tGT, ">",
791
- :tINTEGER, 2)
794
+ :tIDENTIFIER, "a", [0, 1],
795
+ :tGT, ">", [2, 3],
796
+ :tINTEGER, 2, [4, 5])
792
797
  end
793
798
 
794
799
  def test_heredoc_backtick
795
800
  assert_scanned("a = <<`EOF`\n blah blah\nEOF\n",
796
- :tIDENTIFIER, "a",
797
- :tEQL, "=",
798
- :tXSTRING_BEG, "<<`",
799
- :tSTRING_CONTENT, " blah blah\n",
800
- :tSTRING_END, "EOF",
801
- :tNL, nil)
801
+ :tIDENTIFIER, "a", [0, 1],
802
+ :tEQL, "=", [2, 3],
803
+ :tXSTRING_BEG, "<<`", [4, 11],
804
+ :tSTRING_CONTENT, " blah blah\n", [12, 24],
805
+ :tSTRING_END, "EOF", [24, 27],
806
+ :tNL, nil, [11, 12])
802
807
  end
803
808
 
804
809
  def test_heredoc_double
805
810
  assert_scanned("a = <<\"EOF\"\n blah blah\nEOF\n",
806
- :tIDENTIFIER, "a",
807
- :tEQL, "=",
808
- :tSTRING_BEG, "<<\"",
809
- :tSTRING_CONTENT, " blah blah\n",
810
- :tSTRING_END, "EOF",
811
- :tNL, nil)
811
+ :tIDENTIFIER, "a", [0, 1],
812
+ :tEQL, "=", [2, 3],
813
+ :tSTRING_BEG, "<<\"", [4, 11],
814
+ :tSTRING_CONTENT, " blah blah\n", [12, 24],
815
+ :tSTRING_END, "EOF", [24, 27],
816
+ :tNL, nil, [11, 12])
812
817
  end
813
818
 
814
819
  def test_heredoc_double_dash
815
820
  assert_scanned("a = <<-\"EOF\"\n blah blah\n EOF\n",
816
- :tIDENTIFIER, "a",
817
- :tEQL, "=",
818
- :tSTRING_BEG, "<<\"",
819
- :tSTRING_CONTENT, " blah blah\n",
820
- :tSTRING_END, "EOF",
821
- :tNL, nil)
821
+ :tIDENTIFIER, "a", [0, 1],
822
+ :tEQL, "=", [2, 3],
823
+ :tSTRING_BEG, "<<\"", [4, 12],
824
+ :tSTRING_CONTENT, " blah blah\n", [13, 25],
825
+ :tSTRING_END, "EOF", [25, 30],
826
+ :tNL, nil, [12, 13])
822
827
  end
823
828
 
824
829
  def test_heredoc_double_eos
825
830
  refute_scanned("a = <<\"EOF\"\nblah",
826
- :tIDENTIFIER, "a",
827
- :tEQL, "=",
828
- :tSTRING_BEG, "<<\"")
831
+ :tIDENTIFIER, "a", [0, 1],
832
+ :tEQL, "=", [2, 3],
833
+ :tSTRING_BEG, "<<\"", [4, 7])
829
834
  end
830
835
 
831
836
  def test_heredoc_double_eos_nl
832
837
  refute_scanned("a = <<\"EOF\"\nblah\n",
833
- :tIDENTIFIER, "a",
834
- :tEQL, "=",
835
- :tSTRING_BEG, "<<\"")
838
+ :tIDENTIFIER, "a", [0, 1],
839
+ :tEQL, "=", [2, 3],
840
+ :tSTRING_BEG, "<<\"", [4, 7])
836
841
  end
837
842
 
838
843
  def test_heredoc_double_interp
839
844
  assert_scanned("a = <<\"EOF\"\n#x a \#@a b \#$b c \#{3} \nEOF\n",
840
- :tIDENTIFIER, "a",
841
- :tEQL, "=",
842
- :tSTRING_BEG, "<<\"",
843
- :tSTRING_CONTENT, "#x a ",
844
- :tSTRING_DVAR, nil,
845
- :tIVAR, "@a",
846
- :tSTRING_CONTENT, " b ",
847
- :tSTRING_DVAR, nil,
848
- :tGVAR, "$b",
849
- :tSTRING_CONTENT, " c ",
850
- :tSTRING_DBEG, '#{',
851
- :tINTEGER, 3,
852
- :tRCURLY, "}",
853
- :tSTRING_CONTENT, " \n",
854
- :tSTRING_END, "EOF",
855
- :tNL, nil)
845
+ :tIDENTIFIER, "a", [0, 1],
846
+ :tEQL, "=", [2, 3],
847
+ :tSTRING_BEG, "<<\"", [4, 11],
848
+ :tSTRING_CONTENT, "#x a ", [12, 17],
849
+ :tSTRING_DVAR, nil, [17, 18],
850
+ :tIVAR, "@a", [18, 20],
851
+ :tSTRING_CONTENT, " b ", [20, 23],
852
+ :tSTRING_DVAR, nil, [23, 24],
853
+ :tGVAR, "$b", [24, 26],
854
+ :tSTRING_CONTENT, " c ", [26, 29],
855
+ :tSTRING_DBEG, '#{', [29, 31],
856
+ :tINTEGER, 3, [31, 32],
857
+ :tRCURLY, "}", [32, 33],
858
+ :tSTRING_CONTENT, " \n", [33, 35],
859
+ :tSTRING_END, "EOF", [35, 38],
860
+ :tNL, nil, [11, 12])
856
861
  end
857
862
 
858
863
  def test_heredoc_empty
859
864
  assert_scanned("<<\"\"\n\#{x}\nblah2\n\n",
860
- :tSTRING_BEG, "<<\"",
861
- :tSTRING_DBEG, "\#{",
862
- :tIDENTIFIER, "x",
863
- :tRCURLY, "}",
864
- :tSTRING_CONTENT, "\n",
865
- :tSTRING_CONTENT, "blah2\n",
866
- :tSTRING_END, "",
867
- :tNL, nil)
865
+ :tSTRING_BEG, "<<\"", [0, 4],
866
+ :tSTRING_DBEG, "\#{", [5, 7],
867
+ :tIDENTIFIER, "x", [7, 8],
868
+ :tRCURLY, "}", [8, 9],
869
+ :tSTRING_CONTENT, "\n", [9, 10],
870
+ :tSTRING_CONTENT, "blah2\n", [10, 16],
871
+ :tSTRING_END, "", [16, 16],
872
+ :tNL, nil, [4, 5])
868
873
  end
869
874
 
870
875
  def test_heredoc_none
871
876
  assert_scanned("a = <<EOF\nblah\nblah\nEOF",
872
- :tIDENTIFIER, "a",
873
- :tEQL, "=",
874
- :tSTRING_BEG, "<<\"",
875
- :tSTRING_CONTENT, "blah\n",
876
- :tSTRING_CONTENT, "blah\n",
877
- :tSTRING_END, "EOF",
878
- :tNL, nil)
877
+ :tIDENTIFIER, "a", [0, 1],
878
+ :tEQL, "=", [2, 3],
879
+ :tSTRING_BEG, "<<\"", [4, 9],
880
+ :tSTRING_CONTENT, "blah\n", [10, 15],
881
+ :tSTRING_CONTENT, "blah\n", [15, 20],
882
+ :tSTRING_END, "EOF", [20, 23],
883
+ :tNL, nil, [9, 10])
879
884
  end
880
885
 
881
886
  def test_heredoc_none_dash
882
887
  assert_scanned("a = <<-EOF\nblah\nblah\n EOF",
883
- :tIDENTIFIER, "a",
884
- :tEQL, "=",
885
- :tSTRING_BEG, "<<\"",
886
- :tSTRING_CONTENT, "blah\n",
887
- :tSTRING_CONTENT, "blah\n",
888
- :tSTRING_END, "EOF",
889
- :tNL, nil)
888
+ :tIDENTIFIER, "a", [0, 1],
889
+ :tEQL, "=", [2, 3],
890
+ :tSTRING_BEG, "<<\"", [4, 10],
891
+ :tSTRING_CONTENT, "blah\n", [11, 16],
892
+ :tSTRING_CONTENT, "blah\n", [16, 21],
893
+ :tSTRING_END, "EOF", [21, 26],
894
+ :tNL, nil, [10, 11])
890
895
  end
891
896
 
892
897
  def test_heredoc_single
893
898
  assert_scanned("a = <<'EOF'\n blah blah\nEOF\n",
894
- :tIDENTIFIER, "a",
895
- :tEQL, "=",
896
- :tSTRING_BEG, "<<'",
897
- :tSTRING_CONTENT, " blah blah\n",
898
- :tSTRING_END, "EOF",
899
- :tNL, nil)
899
+ :tIDENTIFIER, "a", [0, 1],
900
+ :tEQL, "=", [2, 3],
901
+ :tSTRING_BEG, "<<'", [4, 11],
902
+ :tSTRING_CONTENT, " blah blah\n", [12, 24],
903
+ :tSTRING_END, "EOF", [24, 27],
904
+ :tNL, nil, [11, 12])
900
905
  end
901
906
 
902
907
  def test_heredoc_single_bad_eos_body
903
908
  refute_scanned("a = <<'EOF'\nblah",
904
- :tIDENTIFIER, "a",
905
- :tEQL, "=",
906
- :tSTRING_BEG, "'")
909
+ :tIDENTIFIER, "a", [0, 1],
910
+ :tEQL, "=", [2, 3],
911
+ :tSTRING_BEG, "'", [6, 7])
907
912
  end
908
913
 
909
914
  def test_heredoc_single_dash
910
915
  assert_scanned("a = <<-'EOF'\n blah blah\n EOF\n",
911
- :tIDENTIFIER, "a",
912
- :tEQL, "=",
913
- :tSTRING_BEG, "<<'",
914
- :tSTRING_CONTENT, " blah blah\n",
915
- :tSTRING_END, "EOF",
916
- :tNL, nil)
916
+ :tIDENTIFIER, "a", [0, 1],
917
+ :tEQL, "=", [2, 3],
918
+ :tSTRING_BEG, "<<'", [4, 12],
919
+ :tSTRING_CONTENT, " blah blah\n", [13, 25],
920
+ :tSTRING_END, "EOF", [25, 30],
921
+ :tNL, nil, [12, 13])
917
922
  end
918
923
 
919
924
  def test_heredoc_one_character
920
925
  assert_scanned("a = <<E\nABCDEF\nE\n",
921
- :tIDENTIFIER, "a",
922
- :tEQL, "=",
923
- :tSTRING_BEG, "<<\"",
924
- :tSTRING_CONTENT, "ABCDEF\n",
925
- :tSTRING_END, "E",
926
- :tNL, nil)
926
+ :tIDENTIFIER, "a", [0, 1],
927
+ :tEQL, "=", [2, 3],
928
+ :tSTRING_BEG, "<<\"", [4, 7],
929
+ :tSTRING_CONTENT, "ABCDEF\n", [8, 15],
930
+ :tSTRING_END, "E", [15, 16],
931
+ :tNL, nil, [7, 8])
927
932
  end
928
933
 
929
934
  def test_heredoc_cr
930
935
  assert_scanned("a = <<E\r\r\nABCDEF\r\r\nE\r\r\r\n",
931
- :tIDENTIFIER, "a",
932
- :tEQL, "=",
933
- :tSTRING_BEG, "<<\"",
934
- :tSTRING_CONTENT, "ABCDEF\r\n",
935
- :tSTRING_END, "E",
936
- :tNL, nil)
936
+ :tIDENTIFIER, "a", [0, 1],
937
+ :tEQL, "=", [2, 3],
938
+ :tSTRING_BEG, "<<\"", [4, 7],
939
+ :tSTRING_CONTENT, "ABCDEF\r\n", [9, 17],
940
+ :tSTRING_END, "E", [17, 20],
941
+ :tNL, nil, [8, 9])
937
942
  end
938
943
 
939
944
  def test_identifier
940
945
  assert_scanned("identifier",
941
- :tIDENTIFIER, "identifier")
946
+ :tIDENTIFIER, "identifier", [0, 10])
942
947
  end
943
948
 
944
949
  def test_identifier_bang
945
950
  assert_scanned("identifier!",
946
- :tFID, "identifier!")
951
+ :tFID, "identifier!", [0, 11])
947
952
 
948
953
  assert_scanned("identifier!=",
949
- :tIDENTIFIER, "identifier",
950
- :tNEQ, "!=")
954
+ :tIDENTIFIER, "identifier", [0, 10],
955
+ :tNEQ, "!=", [10, 12])
956
+ end
957
+
958
+ def test_identifier_eh
959
+ assert_scanned("identifier?",
960
+ :tFID, "identifier?", [0, 11])
961
+
962
+ assert_scanned("identifier?=",
963
+ :tIDENTIFIER, "identifier", [0, 10],
964
+ :tNEQ, "?=", [10, 12])
951
965
  end
952
966
 
953
967
  def test_identifier_cmp
954
- assert_lex_fname "<=>", :tCMP
968
+ assert_lex_fname "<=>", :tCMP, [0, 3]
955
969
  end
956
970
 
957
971
  def test_identifier_def
958
- assert_lex_fname "identifier", :tIDENTIFIER
972
+ assert_lex_fname "identifier", :tIDENTIFIER, [0, 10]
959
973
  end
960
974
 
961
975
  def test_identifier_eh
962
- assert_scanned("identifier?", :tFID, "identifier?")
976
+ assert_scanned("identifier?", :tFID, "identifier?", [0, 11])
963
977
  end
964
978
 
965
979
  def test_identifier_equals_arrow
966
980
  assert_scanned(":blah==>",
967
- :tSYMBOL, "blah=",
968
- :tASSOC, "=>")
981
+ :tSYMBOL, "blah=", [0, 6],
982
+ :tASSOC, "=>", [6, 8])
969
983
  end
970
984
 
971
985
  def test_identifier_equals3
972
986
  assert_scanned(":a===b",
973
- :tSYMBOL, "a",
974
- :tEQQ, "===",
975
- :tIDENTIFIER, "b")
987
+ :tSYMBOL, "a", [0, 2],
988
+ :tEQQ, "===", [2, 5],
989
+ :tIDENTIFIER, "b", [5, 6])
976
990
  end
977
991
 
978
992
  def test_identifier_equals_equals_arrow
979
993
  assert_scanned(":a==>b",
980
- :tSYMBOL, "a=",
981
- :tASSOC, "=>",
982
- :tIDENTIFIER, "b")
994
+ :tSYMBOL, "a=", [0, 3],
995
+ :tASSOC, "=>", [3, 5],
996
+ :tIDENTIFIER, "b", [5, 6])
983
997
  end
984
998
 
985
999
  def test_identifier_equals_caret
986
- assert_lex_fname "^", :tCARET
1000
+ assert_lex_fname "^", :tCARET, [0, 1]
987
1001
  end
988
1002
 
989
1003
  def test_identifier_equals_def
990
- assert_lex_fname "identifier=", :tIDENTIFIER
1004
+ assert_lex_fname "identifier=", :tIDENTIFIER, [0, 11]
991
1005
  end
992
1006
 
993
1007
  def test_identifier_equals_def2
994
- assert_lex_fname "==", :tEQ
1008
+ assert_lex_fname "==", :tEQ, [0, 2]
995
1009
  end
996
1010
 
997
1011
  def test_identifier_equals_expr
998
1012
  @lex.state = :expr_dot
999
1013
  assert_scanned("y = arg",
1000
- :tIDENTIFIER, "y",
1001
- :tEQL, "=",
1002
- :tIDENTIFIER, "arg")
1014
+ :tIDENTIFIER, "y", [0, 1],
1015
+ :tEQL, "=", [2, 3],
1016
+ :tIDENTIFIER, "arg", [4, 7])
1003
1017
 
1004
1018
  assert_equal :expr_arg, @lex.state
1005
1019
  end
1006
1020
 
1007
1021
  def test_identifier_equals_or
1008
- assert_lex_fname "|", :tPIPE
1022
+ assert_lex_fname "|", :tPIPE, [0, 1]
1009
1023
  end
1010
1024
 
1011
1025
  def test_identifier_equals_slash
1012
- assert_lex_fname "/", :tDIVIDE
1026
+ assert_lex_fname "/", :tDIVIDE, [0, 1]
1013
1027
  end
1014
1028
 
1015
1029
  def test_identifier_equals_tilde
1016
1030
  @lex.state = :expr_fname
1017
1031
  assert_scanned("identifier=~",
1018
- :tIDENTIFIER, "identifier=",
1019
- :tTILDE, "~")
1032
+ :tIDENTIFIER, "identifier=", [0, 11],
1033
+ :tTILDE, "~", [11, 12])
1020
1034
  end
1021
1035
 
1022
1036
  def test_identifier_gt
1023
- assert_lex_fname ">", :tGT
1037
+ assert_lex_fname ">", :tGT, [0, 1]
1024
1038
  end
1025
1039
 
1026
1040
  def test_identifier_le
1027
- assert_lex_fname "<=", :tLEQ
1041
+ assert_lex_fname "<=", :tLEQ, [0, 2]
1028
1042
  end
1029
1043
 
1030
1044
  def test_identifier_lt
1031
- assert_lex_fname "<", :tLT
1045
+ assert_lex_fname "<", :tLT, [0, 1]
1032
1046
  end
1033
1047
 
1034
1048
  def test_identifier_tilde
1035
- assert_lex_fname "~", :tTILDE
1049
+ assert_lex_fname "~", :tTILDE, [0, 1]
1036
1050
  end
1037
1051
 
1038
1052
  def test_identifier_defined?
1039
- assert_lex_fname "defined?", :kDEFINED
1053
+ assert_lex_fname "defined?", :kDEFINED, [0, 8]
1040
1054
  end
1041
1055
 
1042
1056
  def test_index
1043
- assert_lex_fname "[]", :tAREF
1057
+ assert_lex_fname "[]", :tAREF, [0, 2]
1044
1058
  end
1045
1059
 
1046
1060
  def test_index_equals
1047
- assert_lex_fname "[]=", :tASET
1061
+ assert_lex_fname "[]=", :tASET, [0, 3]
1048
1062
  end
1049
1063
 
1050
1064
  def test_integer
1051
- assert_scanned "42", :tINTEGER, 42
1065
+ assert_scanned "42", :tINTEGER, 42, [0, 2]
1052
1066
  end
1053
1067
 
1054
1068
  def test_integer_bin
1055
- assert_scanned "0b101010", :tINTEGER, 42
1069
+ assert_scanned "0b101010", :tINTEGER, 42, [0, 8]
1056
1070
  end
1057
1071
 
1058
1072
  def test_integer_bin_bad_none
@@ -1064,7 +1078,7 @@ class TestLexer < Minitest::Test
1064
1078
  end
1065
1079
 
1066
1080
  def test_integer_dec
1067
- assert_scanned "42", :tINTEGER, 42
1081
+ assert_scanned "42", :tINTEGER, 42, [0, 2]
1068
1082
  end
1069
1083
 
1070
1084
  def test_integer_dec_bad_underscores
@@ -1072,7 +1086,7 @@ class TestLexer < Minitest::Test
1072
1086
  end
1073
1087
 
1074
1088
  def test_integer_dec_d
1075
- assert_scanned "0d42", :tINTEGER, 42
1089
+ assert_scanned "0d42", :tINTEGER, 42, [0, 4]
1076
1090
  end
1077
1091
 
1078
1092
  def test_integer_dec_d_bad_none
@@ -1086,25 +1100,25 @@ class TestLexer < Minitest::Test
1086
1100
  def test_question_eh_a__18
1087
1101
  setup_lexer 18
1088
1102
 
1089
- assert_scanned "?a", :tINTEGER, 97
1103
+ assert_scanned "?a", :tINTEGER, 97, [0, 2]
1090
1104
  end
1091
1105
 
1092
1106
  def test_question_eh_a__19
1093
1107
  setup_lexer 19
1094
1108
 
1095
- assert_scanned '?a', :tCHARACTER, "a"
1109
+ assert_scanned '?a', :tCHARACTER, "a", [0, 2]
1096
1110
  end
1097
1111
 
1098
1112
  def test_question_eh_escape_M_escape_C__18
1099
1113
  setup_lexer 18
1100
1114
 
1101
- assert_scanned '?\M-\C-a', :tINTEGER, 129
1115
+ assert_scanned '?\M-\C-a', :tINTEGER, 129, [0, 8]
1102
1116
  end
1103
1117
 
1104
1118
  def test_question_eh_escape_M_escape_C__19
1105
1119
  setup_lexer 19
1106
1120
 
1107
- assert_scanned '?\M-\C-a', :tCHARACTER, "\M-\C-a"
1121
+ assert_scanned '?\M-\C-a', :tCHARACTER, "\M-\C-a", [0, 8]
1108
1122
  end
1109
1123
 
1110
1124
  def test_question_eh_escape_u_1_digit
@@ -1128,17 +1142,17 @@ class TestLexer < Minitest::Test
1128
1142
  def test_question_eh_escape_u_4_digits
1129
1143
  if RUBY_VERSION >= '1.9'
1130
1144
  setup_lexer 19
1131
- assert_scanned '?\\u0001', :tCHARACTER, "\u0001"
1145
+ assert_scanned '?\\u0001', :tCHARACTER, "\u0001", [0, 7]
1132
1146
  end
1133
1147
  end
1134
1148
 
1135
1149
  def test_question_eh_single_unicode_point
1136
1150
  if RUBY_VERSION >= '1.9'
1137
1151
  setup_lexer 19
1138
- assert_scanned '?\\u{123}', :tCHARACTER, "\u0123"
1152
+ assert_scanned '?\\u{123}', :tCHARACTER, "\u0123", [0, 8]
1139
1153
 
1140
1154
  setup_lexer 19
1141
- assert_scanned '?\\u{a}', :tCHARACTER, "\n"
1155
+ assert_scanned '?\\u{a}', :tCHARACTER, "\n", [0, 6]
1142
1156
  end
1143
1157
  end
1144
1158
 
@@ -1157,7 +1171,7 @@ class TestLexer < Minitest::Test
1157
1171
  end
1158
1172
 
1159
1173
  def test_integer_hex
1160
- assert_scanned "0x2a", :tINTEGER, 42
1174
+ assert_scanned "0x2a", :tINTEGER, 42, [0, 4]
1161
1175
  end
1162
1176
 
1163
1177
  def test_integer_hex_bad_none
@@ -1169,7 +1183,7 @@ class TestLexer < Minitest::Test
1169
1183
  end
1170
1184
 
1171
1185
  def test_integer_oct
1172
- assert_scanned "052", :tINTEGER, 42
1186
+ assert_scanned "052", :tINTEGER, 42, [0, 3]
1173
1187
  end
1174
1188
 
1175
1189
  def test_integer_oct_bad_range
@@ -1181,7 +1195,7 @@ class TestLexer < Minitest::Test
1181
1195
  end
1182
1196
 
1183
1197
  def test_integer_oct_O
1184
- assert_scanned "0O52", :tINTEGER, 42
1198
+ assert_scanned "0O52", :tINTEGER, 42, [0, 4]
1185
1199
  end
1186
1200
 
1187
1201
  def test_integer_oct_O_bad_range
@@ -1193,11 +1207,11 @@ class TestLexer < Minitest::Test
1193
1207
  end
1194
1208
 
1195
1209
  def test_integer_oct_O_not_bad_none
1196
- assert_scanned "0O ", :tINTEGER, 0
1210
+ assert_scanned "0O ", :tINTEGER, 0, [0, 2]
1197
1211
  end
1198
1212
 
1199
1213
  def test_integer_oct_o
1200
- assert_scanned "0o52", :tINTEGER, 42
1214
+ assert_scanned "0o52", :tINTEGER, 42, [0, 4]
1201
1215
  end
1202
1216
 
1203
1217
  def test_integer_oct_o_bad_range
@@ -1209,18 +1223,18 @@ class TestLexer < Minitest::Test
1209
1223
  end
1210
1224
 
1211
1225
  def test_integer_oct_o_not_bad_none
1212
- assert_scanned "0o ", :tINTEGER, 0
1226
+ assert_scanned "0o ", :tINTEGER, 0, [0, 2]
1213
1227
  end
1214
1228
 
1215
1229
  def test_integer_trailing
1216
1230
  assert_scanned("1.to_s",
1217
- :tINTEGER, 1,
1218
- :tDOT, '.',
1219
- :tIDENTIFIER, 'to_s')
1231
+ :tINTEGER, 1, [0, 1],
1232
+ :tDOT, '.', [1, 2],
1233
+ :tIDENTIFIER, 'to_s', [2, 6])
1220
1234
  end
1221
1235
 
1222
1236
  def test_integer_underscore
1223
- assert_scanned "4_2", :tINTEGER, 42
1237
+ assert_scanned "4_2", :tINTEGER, 42, [0, 3]
1224
1238
  end
1225
1239
 
1226
1240
  def test_integer_underscore_bad
@@ -1228,11 +1242,11 @@ class TestLexer < Minitest::Test
1228
1242
  end
1229
1243
 
1230
1244
  def test_integer_zero
1231
- assert_scanned "0", :tINTEGER, 0
1245
+ assert_scanned "0", :tINTEGER, 0, [0, 1]
1232
1246
  end
1233
1247
 
1234
1248
  def test_ivar
1235
- assert_scanned "@blah", :tIVAR, "@blah"
1249
+ assert_scanned "@blah", :tIVAR, "@blah", [0, 5]
1236
1250
  end
1237
1251
 
1238
1252
  def test_ivar_bad
@@ -1240,215 +1254,215 @@ class TestLexer < Minitest::Test
1240
1254
  end
1241
1255
 
1242
1256
  def test_ivar_bad_0_length
1243
- refute_scanned "1+@\n", :tINTEGER, 1, :tPLUS, "+"
1257
+ refute_scanned "1+@\n", :tINTEGER, 1, [0, 1], :tPLUS, "+", [1, 2]
1244
1258
  end
1245
1259
 
1246
1260
  def test_keyword_expr
1247
1261
  @lex.state = :expr_endarg
1248
1262
 
1249
- assert_scanned("if", :kIF_MOD, "if")
1263
+ assert_scanned "if", :kIF_MOD, "if", [0, 2]
1250
1264
 
1251
1265
  assert_equal :expr_beg, @lex.state
1252
1266
  end
1253
1267
 
1254
1268
  def test_lt
1255
- assert_scanned "<", :tLT, "<"
1269
+ assert_scanned "<", :tLT, "<", [0, 1]
1256
1270
  end
1257
1271
 
1258
1272
  def test_lt2
1259
1273
  assert_scanned("a <\< b",
1260
- :tIDENTIFIER, "a",
1261
- :tLSHFT, "<\<",
1262
- :tIDENTIFIER, "b")
1274
+ :tIDENTIFIER, "a", [0, 1],
1275
+ :tLSHFT, "<\<", [2, 4],
1276
+ :tIDENTIFIER, "b", [5, 6])
1263
1277
 
1264
1278
  end
1265
1279
 
1266
1280
  def test_lt2_equals
1267
1281
  assert_scanned("a <\<= b",
1268
- :tIDENTIFIER, "a",
1269
- :tOP_ASGN, "<\<",
1270
- :tIDENTIFIER, "b")
1282
+ :tIDENTIFIER, "a", [0, 1],
1283
+ :tOP_ASGN, "<\<", [2, 5],
1284
+ :tIDENTIFIER, "b", [6, 7])
1271
1285
  end
1272
1286
 
1273
1287
  def test_lt_equals
1274
- assert_scanned "<=", :tLEQ, "<="
1288
+ assert_scanned "<=", :tLEQ, "<=", [0, 2]
1275
1289
  end
1276
1290
 
1277
1291
  def test_minus
1278
1292
  assert_scanned("1 - 2",
1279
- :tINTEGER, 1,
1280
- :tMINUS, "-",
1281
- :tINTEGER, 2)
1293
+ :tINTEGER, 1, [0, 1],
1294
+ :tMINUS, "-", [2, 3],
1295
+ :tINTEGER, 2, [4, 5])
1282
1296
  end
1283
1297
 
1284
1298
  def test_minus_equals
1285
1299
  @lex.state = :expr_end
1286
1300
 
1287
- assert_scanned "-=", :tOP_ASGN, "-"
1301
+ assert_scanned "-=", :tOP_ASGN, "-", [0, 2]
1288
1302
  end
1289
1303
 
1290
1304
  def test_minus_method
1291
1305
  @lex.state = :expr_fname
1292
- assert_scanned "-", :tMINUS, "-"
1306
+ assert_scanned "-", :tMINUS, "-", [0, 1]
1293
1307
  end
1294
1308
 
1295
1309
  def test_minus_unary_method
1296
1310
  @lex.state = :expr_fname
1297
- assert_scanned "-@", :tUMINUS, "-@"
1311
+ assert_scanned "-@", :tUMINUS, "-@", [0, 2]
1298
1312
  end
1299
1313
 
1300
1314
  def test_minus_unary_number
1301
1315
  assert_scanned("-42",
1302
- :tUMINUS_NUM, "-",
1303
- :tINTEGER, 42)
1316
+ :tUMINUS_NUM, "-", [0, 1],
1317
+ :tINTEGER, 42, [1, 3])
1304
1318
  end
1305
1319
 
1306
1320
  def test_nth_ref
1307
1321
  assert_scanned('[$1, $2, $3]',
1308
- :tLBRACK, "[",
1309
- :tNTH_REF, 1, :tCOMMA, ",",
1310
- :tNTH_REF, 2, :tCOMMA, ",",
1311
- :tNTH_REF, 3,
1312
- :tRBRACK, "]")
1322
+ :tLBRACK, "[", [0, 1],
1323
+ :tNTH_REF, 1, [1, 3], :tCOMMA, ",", [3, 4],
1324
+ :tNTH_REF, 2, [5, 7], :tCOMMA, ",", [7, 8],
1325
+ :tNTH_REF, 3, [9, 11],
1326
+ :tRBRACK, "]", [11, 12])
1313
1327
  end
1314
1328
 
1315
1329
  def test_open_bracket
1316
- assert_scanned("(", :tLPAREN, "(")
1330
+ assert_scanned("(", :tLPAREN, "(", [0, 1])
1317
1331
  end
1318
1332
 
1319
1333
  def test_open_bracket_cmdarg
1320
- assert_scanned("m (", :tIDENTIFIER, "m",
1321
- :tLPAREN_ARG, "(")
1334
+ assert_scanned("m (", :tIDENTIFIER, "m", [0, 1],
1335
+ :tLPAREN_ARG, "(", [2, 3])
1322
1336
  end
1323
1337
 
1324
1338
  def test_open_bracket_exprarg
1325
- assert_scanned("m(", :tIDENTIFIER, "m",
1326
- :tLPAREN2, "(")
1339
+ assert_scanned("m(", :tIDENTIFIER, "m", [0, 1],
1340
+ :tLPAREN2, "(", [1, 2])
1327
1341
  end
1328
1342
 
1329
1343
  def test_open_curly_bracket
1330
1344
  assert_scanned("{",
1331
- :tLBRACE, "{")
1345
+ :tLBRACE, "{", [0, 1])
1332
1346
  end
1333
1347
 
1334
1348
  def test_open_curly_bracket_arg
1335
1349
  assert_scanned("m { 3 }",
1336
- :tIDENTIFIER, "m",
1337
- :tLCURLY, "{",
1338
- :tINTEGER, 3,
1339
- :tRCURLY, "}")
1350
+ :tIDENTIFIER, "m", [0, 1],
1351
+ :tLCURLY, "{", [2, 3],
1352
+ :tINTEGER, 3, [4, 5],
1353
+ :tRCURLY, "}", [6, 7])
1340
1354
  end
1341
1355
 
1342
1356
  def test_open_curly_bracket_block
1343
1357
  @lex.state = :expr_endarg # seen m(3)
1344
1358
 
1345
1359
  assert_scanned("{ 4 }",
1346
- :tLBRACE_ARG, "{",
1347
- :tINTEGER, 4,
1348
- :tRCURLY, "}")
1360
+ :tLBRACE_ARG, "{", [0, 1],
1361
+ :tINTEGER, 4, [2, 3],
1362
+ :tRCURLY, "}", [4, 5])
1349
1363
  end
1350
1364
 
1351
1365
  def test_open_square_bracket_arg
1352
1366
  assert_scanned("m [ 3 ]",
1353
- :tIDENTIFIER, "m",
1354
- :tLBRACK, "[",
1355
- :tINTEGER, 3,
1356
- :tRBRACK, "]")
1367
+ :tIDENTIFIER, "m", [0, 1],
1368
+ :tLBRACK, "[", [2, 3],
1369
+ :tINTEGER, 3, [4, 5],
1370
+ :tRBRACK, "]", [6, 7])
1357
1371
  end
1358
1372
 
1359
1373
  def test_open_square_bracket_ary
1360
1374
  assert_scanned("[1, 2, 3]",
1361
- :tLBRACK, "[",
1362
- :tINTEGER, 1,
1363
- :tCOMMA, ",",
1364
- :tINTEGER, 2,
1365
- :tCOMMA, ",",
1366
- :tINTEGER, 3,
1367
- :tRBRACK, "]")
1375
+ :tLBRACK, "[", [0, 1],
1376
+ :tINTEGER, 1, [1, 2],
1377
+ :tCOMMA, ",", [2, 3],
1378
+ :tINTEGER, 2, [4, 5],
1379
+ :tCOMMA, ",", [5, 6],
1380
+ :tINTEGER, 3, [7, 8],
1381
+ :tRBRACK, "]", [8, 9])
1368
1382
  end
1369
1383
 
1370
1384
  def test_open_square_bracket_meth
1371
1385
  assert_scanned("m[3]",
1372
- :tIDENTIFIER, "m",
1373
- :tLBRACK2, "[",
1374
- :tINTEGER, 3,
1375
- :tRBRACK, "]")
1386
+ :tIDENTIFIER, "m", [0, 1],
1387
+ :tLBRACK2, "[", [1, 2],
1388
+ :tINTEGER, 3, [2, 3],
1389
+ :tRBRACK, "]", [3, 4])
1376
1390
  end
1377
1391
 
1378
1392
  def test_or
1379
- assert_scanned "|", :tPIPE, "|"
1393
+ assert_scanned "|", :tPIPE, "|", [0, 1]
1380
1394
  end
1381
1395
 
1382
1396
  def test_or2
1383
- assert_scanned "||", :tOROP, "||"
1397
+ assert_scanned "||", :tOROP, "||", [0, 2]
1384
1398
  end
1385
1399
 
1386
1400
  def test_or2_equals
1387
- assert_scanned "||=", :tOP_ASGN, "||"
1401
+ assert_scanned "||=", :tOP_ASGN, "||", [0, 3]
1388
1402
  end
1389
1403
 
1390
1404
  def test_or_equals
1391
- assert_scanned "|=", :tOP_ASGN, "|"
1405
+ assert_scanned "|=", :tOP_ASGN, "|", [0, 2]
1392
1406
  end
1393
1407
 
1394
1408
  def test_percent
1395
1409
  assert_scanned("a % 2",
1396
- :tIDENTIFIER, "a",
1397
- :tPERCENT, "%",
1398
- :tINTEGER, 2)
1410
+ :tIDENTIFIER, "a", [0, 1],
1411
+ :tPERCENT, "%", [2, 3],
1412
+ :tINTEGER, 2, [4, 5])
1399
1413
  end
1400
1414
 
1401
1415
  def test_percent_equals
1402
1416
  assert_scanned("a %= 2",
1403
- :tIDENTIFIER, "a",
1404
- :tOP_ASGN, "%",
1405
- :tINTEGER, 2)
1417
+ :tIDENTIFIER, "a", [0, 1],
1418
+ :tOP_ASGN, "%", [2, 4],
1419
+ :tINTEGER, 2, [5, 6])
1406
1420
  end
1407
1421
 
1408
1422
  def test_plus
1409
1423
  assert_scanned("1 + 1",
1410
- :tINTEGER, 1,
1411
- :tPLUS, "+",
1412
- :tINTEGER, 1)
1424
+ :tINTEGER, 1, [0, 1],
1425
+ :tPLUS, "+", [2, 3],
1426
+ :tINTEGER, 1, [4, 5])
1413
1427
  end
1414
1428
 
1415
1429
  def test_plus_equals
1416
1430
  @lex.state = :expr_end
1417
1431
 
1418
- assert_scanned "+=", :tOP_ASGN, "+"
1432
+ assert_scanned "+=", :tOP_ASGN, "+", [0, 2]
1419
1433
  end
1420
1434
 
1421
1435
  def test_plus_method
1422
1436
  @lex.state = :expr_fname
1423
- assert_scanned "+", :tPLUS, "+"
1437
+ assert_scanned "+", :tPLUS, "+", [0, 1]
1424
1438
  end
1425
1439
 
1426
1440
  def test_plus_unary_method
1427
1441
  @lex.state = :expr_fname
1428
- assert_scanned "+@", :tUPLUS, "+@"
1442
+ assert_scanned "+@", :tUPLUS, "+@", [0, 2]
1429
1443
  end
1430
1444
 
1431
1445
  def test_numbers
1432
- assert_scanned "0b10", :tINTEGER, 2
1433
- assert_scanned "0B10", :tINTEGER, 2
1446
+ assert_scanned "0b10", :tINTEGER, 2, [0, 4]
1447
+ assert_scanned "0B10", :tINTEGER, 2, [0, 4]
1434
1448
 
1435
- assert_scanned "0d10", :tINTEGER, 10
1436
- assert_scanned "0D10", :tINTEGER, 10
1449
+ assert_scanned "0d10", :tINTEGER, 10, [0, 4]
1450
+ assert_scanned "0D10", :tINTEGER, 10, [0, 4]
1437
1451
 
1438
- assert_scanned "0x10", :tINTEGER, 16
1439
- assert_scanned "0X10", :tINTEGER, 16
1452
+ assert_scanned "0x10", :tINTEGER, 16, [0, 4]
1453
+ assert_scanned "0X10", :tINTEGER, 16, [0, 4]
1440
1454
 
1441
- assert_scanned "0o10", :tINTEGER, 8
1442
- assert_scanned "0O10", :tINTEGER, 8
1443
- assert_scanned "0o", :tINTEGER, 0
1444
- assert_scanned "0O", :tINTEGER, 0
1455
+ assert_scanned "0o10", :tINTEGER, 8, [0, 4]
1456
+ assert_scanned "0O10", :tINTEGER, 8, [0, 4]
1457
+ assert_scanned "0o", :tINTEGER, 0, [0, 2]
1458
+ assert_scanned "0O", :tINTEGER, 0, [0, 2]
1445
1459
 
1446
- assert_scanned "0o", :tINTEGER, 0
1447
- assert_scanned "0O", :tINTEGER, 0
1460
+ assert_scanned "0o", :tINTEGER, 0, [0, 2]
1461
+ assert_scanned "0O", :tINTEGER, 0, [0, 2]
1448
1462
 
1449
- assert_scanned "0777_333", :tINTEGER, 261851
1463
+ assert_scanned "0777_333", :tINTEGER, 261851, [0, 8]
1450
1464
 
1451
- assert_scanned "0", :tINTEGER, 0
1465
+ assert_scanned "0", :tINTEGER, 0, [0, 1]
1452
1466
 
1453
1467
  refute_scanned "0x"
1454
1468
  refute_scanned "0X"
@@ -1474,19 +1488,19 @@ class TestLexer < Minitest::Test
1474
1488
 
1475
1489
  def test_plus_unary_number
1476
1490
  assert_scanned("+42",
1477
- :tINTEGER, 42)
1491
+ :tINTEGER, 42, [1, 3])
1478
1492
  end
1479
1493
 
1480
1494
  def test_question__18
1481
1495
  setup_lexer 18
1482
1496
 
1483
- assert_scanned "?*", :tINTEGER, 42
1497
+ assert_scanned "?*", :tINTEGER, 42, [0, 2]
1484
1498
  end
1485
1499
 
1486
1500
  def test_question__19
1487
1501
  setup_lexer 19
1488
1502
 
1489
- assert_scanned "?*", :tCHARACTER, "*"
1503
+ assert_scanned "?*", :tCHARACTER, "*", [0, 2]
1490
1504
  end
1491
1505
 
1492
1506
  def test_question_bad_eos
@@ -1494,369 +1508,369 @@ class TestLexer < Minitest::Test
1494
1508
  end
1495
1509
 
1496
1510
  def test_question_bad_ws
1497
- assert_scanned "? ", :tEH, "?"
1498
- assert_scanned "?\n", :tEH, "?"
1499
- assert_scanned "?\t", :tEH, "?"
1500
- assert_scanned "?\v", :tEH, "?"
1501
- assert_scanned "?\r", :tEH, "?"
1502
- assert_scanned "?\f", :tEH, "?"
1511
+ assert_scanned "? ", :tEH, "?", [0, 1]
1512
+ assert_scanned "?\n", :tEH, "?", [0, 1]
1513
+ assert_scanned "?\t", :tEH, "?", [0, 1]
1514
+ assert_scanned "?\v", :tEH, "?", [0, 1]
1515
+ assert_scanned "?\r", :tEH, "?", [0, 1]
1516
+ assert_scanned "?\f", :tEH, "?", [0, 1]
1503
1517
  end
1504
1518
 
1505
1519
  def test_question_ws_backslashed__18
1506
1520
  setup_lexer 18
1507
1521
 
1508
1522
  @lex.state = :expr_beg
1509
- assert_scanned "?\\ ", :tINTEGER, 32
1523
+ assert_scanned "?\\ ", :tINTEGER, 32, [0, 3]
1510
1524
  @lex.state = :expr_beg
1511
- assert_scanned "?\\n", :tINTEGER, 10
1525
+ assert_scanned "?\\n", :tINTEGER, 10, [0, 3]
1512
1526
  @lex.state = :expr_beg
1513
- assert_scanned "?\\t", :tINTEGER, 9
1527
+ assert_scanned "?\\t", :tINTEGER, 9, [0, 3]
1514
1528
  @lex.state = :expr_beg
1515
- assert_scanned "?\\v", :tINTEGER, 11
1529
+ assert_scanned "?\\v", :tINTEGER, 11, [0, 3]
1516
1530
  @lex.state = :expr_beg
1517
- assert_scanned "?\\r", :tINTEGER, 13
1531
+ assert_scanned "?\\r", :tINTEGER, 13, [0, 3]
1518
1532
  @lex.state = :expr_beg
1519
- assert_scanned "?\\f", :tINTEGER, 12
1533
+ assert_scanned "?\\f", :tINTEGER, 12, [0, 3]
1520
1534
  end
1521
1535
 
1522
1536
  def test_question_ws_backslashed__19
1523
1537
  setup_lexer 19
1524
1538
 
1525
1539
  @lex.state = :expr_beg
1526
- assert_scanned "?\\ ", :tCHARACTER, " "
1540
+ assert_scanned "?\\ ", :tCHARACTER, " ", [0, 3]
1527
1541
  @lex.state = :expr_beg
1528
- assert_scanned "?\\n", :tCHARACTER, "\n"
1542
+ assert_scanned "?\\n", :tCHARACTER, "\n", [0, 3]
1529
1543
  @lex.state = :expr_beg
1530
- assert_scanned "?\\t", :tCHARACTER, "\t"
1544
+ assert_scanned "?\\t", :tCHARACTER, "\t", [0, 3]
1531
1545
  @lex.state = :expr_beg
1532
- assert_scanned "?\\v", :tCHARACTER, "\v"
1546
+ assert_scanned "?\\v", :tCHARACTER, "\v", [0, 3]
1533
1547
  @lex.state = :expr_beg
1534
- assert_scanned "?\\r", :tCHARACTER, "\r"
1548
+ assert_scanned "?\\r", :tCHARACTER, "\r", [0, 3]
1535
1549
  @lex.state = :expr_beg
1536
- assert_scanned "?\\f", :tCHARACTER, "\f"
1550
+ assert_scanned "?\\f", :tCHARACTER, "\f", [0, 3]
1537
1551
  end
1538
1552
 
1539
1553
  def test_rbracket
1540
- assert_scanned "]", :tRBRACK, "]"
1554
+ assert_scanned "]", :tRBRACK, "]", [0, 1]
1541
1555
  end
1542
1556
 
1543
1557
  def test_rcurly
1544
- assert_scanned "}", :tRCURLY, "}"
1558
+ assert_scanned "}", :tRCURLY, "}", [0, 1]
1545
1559
  end
1546
1560
 
1547
1561
  def test_regexp
1548
1562
  assert_scanned("/regexp/",
1549
- :tREGEXP_BEG, "/",
1550
- :tSTRING_CONTENT, "regexp",
1551
- :tSTRING_END, "/",
1552
- :tREGEXP_OPT, "")
1563
+ :tREGEXP_BEG, "/", [0, 1],
1564
+ :tSTRING_CONTENT, "regexp", [1, 7],
1565
+ :tSTRING_END, "/", [7, 8],
1566
+ :tREGEXP_OPT, "", [8, 8])
1553
1567
  end
1554
1568
 
1555
1569
  def test_regexp_ambiguous
1556
1570
  assert_scanned("method /regexp/",
1557
- :tIDENTIFIER, "method",
1558
- :tREGEXP_BEG, "/",
1559
- :tSTRING_CONTENT, "regexp",
1560
- :tSTRING_END, "/",
1561
- :tREGEXP_OPT, "")
1571
+ :tIDENTIFIER, "method", [0, 6],
1572
+ :tREGEXP_BEG, "/", [7, 8],
1573
+ :tSTRING_CONTENT, "regexp", [8, 14],
1574
+ :tSTRING_END, "/", [14, 15],
1575
+ :tREGEXP_OPT, "", [15, 15])
1562
1576
  end
1563
1577
 
1564
1578
  def test_regexp_bad
1565
1579
  refute_scanned("/.*/xyz",
1566
- :tREGEXP_BEG, "/",
1567
- :tSTRING_CONTENT, ".*",
1568
- :tSTRING_END, "/")
1580
+ :tREGEXP_BEG, "/", [0, 1],
1581
+ :tSTRING_CONTENT, ".*", [1, 3],
1582
+ :tSTRING_END, "/", [3, 4])
1569
1583
  end
1570
1584
 
1571
1585
  def test_regexp_escape_C
1572
1586
  assert_scanned('/regex\\C-x/',
1573
- :tREGEXP_BEG, "/",
1574
- :tSTRING_CONTENT, "regex\\C-x",
1575
- :tSTRING_END, "/",
1576
- :tREGEXP_OPT, "")
1587
+ :tREGEXP_BEG, "/", [0, 1],
1588
+ :tSTRING_CONTENT, "regex\\C-x", [1, 10],
1589
+ :tSTRING_END, "/", [10, 11],
1590
+ :tREGEXP_OPT, "", [11, 11])
1577
1591
  end
1578
1592
 
1579
1593
  def test_regexp_escape_C_M
1580
1594
  assert_scanned('/regex\\C-\\M-x/',
1581
- :tREGEXP_BEG, "/",
1582
- :tSTRING_CONTENT, "regex\\C-\\M-x",
1583
- :tSTRING_END, "/",
1584
- :tREGEXP_OPT, "")
1595
+ :tREGEXP_BEG, "/", [0, 1],
1596
+ :tSTRING_CONTENT, "regex\\C-\\M-x", [1, 13],
1597
+ :tSTRING_END, "/", [13, 14],
1598
+ :tREGEXP_OPT, "", [14, 14])
1585
1599
  end
1586
1600
 
1587
1601
  def test_regexp_escape_C_M_craaaazy
1588
1602
  assert_scanned("/regex\\C-\\\n\\M-x/",
1589
- :tREGEXP_BEG, "/",
1590
- :tSTRING_CONTENT, "regex\\C-\\M-x",
1591
- :tSTRING_END, "/",
1592
- :tREGEXP_OPT, "")
1603
+ :tREGEXP_BEG, "/", [0, 1],
1604
+ :tSTRING_CONTENT, "regex\\C-\\M-x", [1, 15],
1605
+ :tSTRING_END, "/", [15, 16],
1606
+ :tREGEXP_OPT, "", [16, 16])
1593
1607
  end
1594
1608
 
1595
1609
  def test_regexp_escape_C_bad_dash
1596
- refute_scanned '/regex\\Cx/', :tREGEXP_BEG, "/"
1610
+ refute_scanned '/regex\\Cx/', :tREGEXP_BEG, "/", [0, 1]
1597
1611
  end
1598
1612
 
1599
1613
  def test_regexp_escape_C_bad_dash_eos
1600
- refute_scanned '/regex\\C-/', :tREGEXP_BEG, "/"
1614
+ refute_scanned '/regex\\C-/', :tREGEXP_BEG, "/", [0, 1]
1601
1615
  end
1602
1616
 
1603
1617
  def test_regexp_escape_C_bad_dash_eos2
1604
- refute_scanned '/regex\\C-', :tREGEXP_BEG, "/"
1618
+ refute_scanned '/regex\\C-', :tREGEXP_BEG, "/", [0, 1]
1605
1619
  end
1606
1620
 
1607
1621
  def test_regexp_escape_C_bad_eos
1608
- refute_scanned '/regex\\C/', :tREGEXP_BEG, "/"
1622
+ refute_scanned '/regex\\C/', :tREGEXP_BEG, "/", [0, 1]
1609
1623
  end
1610
1624
 
1611
1625
  def test_regexp_escape_C_bad_eos2
1612
- refute_scanned '/regex\\c', :tREGEXP_BEG, "/"
1626
+ refute_scanned '/regex\\c', :tREGEXP_BEG, "/", [0, 1]
1613
1627
  end
1614
1628
 
1615
1629
  def test_regexp_escape_M
1616
1630
  assert_scanned('/regex\\M-x/',
1617
- :tREGEXP_BEG, "/",
1618
- :tSTRING_CONTENT, "regex\\M-x",
1619
- :tSTRING_END, "/",
1620
- :tREGEXP_OPT, "")
1631
+ :tREGEXP_BEG, "/", [0, 1],
1632
+ :tSTRING_CONTENT, "regex\\M-x", [1, 10],
1633
+ :tSTRING_END, "/", [10, 11],
1634
+ :tREGEXP_OPT, "", [11, 11])
1621
1635
  end
1622
1636
 
1623
1637
  def test_regexp_escape_M_C
1624
1638
  assert_scanned('/regex\\M-\\C-x/',
1625
- :tREGEXP_BEG, "/",
1626
- :tSTRING_CONTENT, "regex\\M-\\C-x",
1627
- :tSTRING_END, "/",
1628
- :tREGEXP_OPT, "")
1639
+ :tREGEXP_BEG, "/", [0, 1],
1640
+ :tSTRING_CONTENT, "regex\\M-\\C-x", [1, 13],
1641
+ :tSTRING_END, "/", [13, 14],
1642
+ :tREGEXP_OPT, "", [14, 14])
1629
1643
  end
1630
1644
 
1631
1645
  def test_regexp_escape_M_bad_dash
1632
- refute_scanned '/regex\\Mx/', :tREGEXP_BEG, "/"
1646
+ refute_scanned '/regex\\Mx/', :tREGEXP_BEG, "/", [0, 1]
1633
1647
  end
1634
1648
 
1635
1649
  def test_regexp_escape_M_bad_dash_eos
1636
- refute_scanned '/regex\\M-/', :tREGEXP_BEG, "/"
1650
+ refute_scanned '/regex\\M-/', :tREGEXP_BEG, "/", [0, 1]
1637
1651
  end
1638
1652
 
1639
1653
  def test_regexp_escape_M_bad_dash_eos2
1640
- refute_scanned '/regex\\M-', :tREGEXP_BEG, "/"
1654
+ refute_scanned '/regex\\M-', :tREGEXP_BEG, "/", [0, 1]
1641
1655
  end
1642
1656
 
1643
1657
  def test_regexp_escape_M_bad_eos
1644
- refute_scanned '/regex\\M/', :tREGEXP_BEG, "/"
1658
+ refute_scanned '/regex\\M/', :tREGEXP_BEG, "/", [0, 1]
1645
1659
  end
1646
1660
 
1647
1661
  def test_regexp_escape_backslash_slash
1648
1662
  assert_scanned('/\\//',
1649
- :tREGEXP_BEG, "/",
1650
- :tSTRING_CONTENT, '/',
1651
- :tSTRING_END, "/",
1652
- :tREGEXP_OPT, "")
1663
+ :tREGEXP_BEG, "/", [0, 1],
1664
+ :tSTRING_CONTENT, '/', [1, 3],
1665
+ :tSTRING_END, "/", [3, 4],
1666
+ :tREGEXP_OPT, "", [4, 4])
1653
1667
  end
1654
1668
 
1655
1669
  def test_regexp_escape_backslash_terminator
1656
1670
  assert_scanned('%r%blah\\%blah%',
1657
- :tREGEXP_BEG, "%r%",
1658
- :tSTRING_CONTENT, "blah%blah",
1659
- :tSTRING_END, "%",
1660
- :tREGEXP_OPT, "")
1671
+ :tREGEXP_BEG, "%r%", [0, 3],
1672
+ :tSTRING_CONTENT, "blah%blah", [3, 13],
1673
+ :tSTRING_END, "%", [13, 14],
1674
+ :tREGEXP_OPT, "", [14, 14])
1661
1675
  end
1662
1676
 
1663
1677
  def test_regexp_escape_backslash_terminator_meta1
1664
1678
  assert_scanned('%r{blah\\}blah}',
1665
- :tREGEXP_BEG, "%r{",
1666
- :tSTRING_CONTENT, "blah\\}blah",
1667
- :tSTRING_END, "}",
1668
- :tREGEXP_OPT, "")
1679
+ :tREGEXP_BEG, "%r{", [0, 3],
1680
+ :tSTRING_CONTENT, "blah\\}blah", [3, 13],
1681
+ :tSTRING_END, "}", [13, 14],
1682
+ :tREGEXP_OPT, "", [14, 14])
1669
1683
  end
1670
1684
 
1671
1685
  def test_regexp_escape_backslash_terminator_meta2
1672
1686
  assert_scanned('%r/blah\\/blah/',
1673
- :tREGEXP_BEG, "%r/",
1674
- :tSTRING_CONTENT, "blah/blah",
1675
- :tSTRING_END, "/",
1676
- :tREGEXP_OPT, "")
1687
+ :tREGEXP_BEG, "%r/", [0, 3],
1688
+ :tSTRING_CONTENT, "blah/blah", [3, 13],
1689
+ :tSTRING_END, "/", [13, 14],
1690
+ :tREGEXP_OPT, "", [14, 14])
1677
1691
  end
1678
1692
 
1679
1693
  def test_regexp_escape_backslash_terminator_meta3
1680
1694
  assert_scanned('%r/blah\\%blah/',
1681
- :tREGEXP_BEG, "%r/",
1682
- :tSTRING_CONTENT, "blah\\%blah",
1683
- :tSTRING_END, "/",
1684
- :tREGEXP_OPT, "")
1695
+ :tREGEXP_BEG, "%r/", [0, 3],
1696
+ :tSTRING_CONTENT, "blah\\%blah", [3, 13],
1697
+ :tSTRING_END, "/", [13, 14],
1698
+ :tREGEXP_OPT, "", [14, 14])
1685
1699
  end
1686
1700
 
1687
1701
  def test_regexp_escape_bad_eos
1688
- refute_scanned '/regex\\', :tREGEXP_BEG, "/"
1702
+ refute_scanned '/regex\\', :tREGEXP_BEG, "/", [0, 1]
1689
1703
  end
1690
1704
 
1691
1705
  def test_regexp_escape_bs
1692
1706
  assert_scanned('/regex\\\\regex/',
1693
- :tREGEXP_BEG, "/",
1694
- :tSTRING_CONTENT, "regex\\\\regex",
1695
- :tSTRING_END, "/",
1696
- :tREGEXP_OPT, "")
1707
+ :tREGEXP_BEG, "/", [0, 1],
1708
+ :tSTRING_CONTENT, "regex\\\\regex", [1, 13],
1709
+ :tSTRING_END, "/", [13, 14],
1710
+ :tREGEXP_OPT, "", [14, 14])
1697
1711
  end
1698
1712
 
1699
1713
  def test_regexp_escape_c
1700
1714
  assert_scanned('/regex\\cxxx/',
1701
- :tREGEXP_BEG, "/",
1702
- :tSTRING_CONTENT, "regex\\cxxx",
1703
- :tSTRING_END, "/",
1704
- :tREGEXP_OPT, "")
1715
+ :tREGEXP_BEG, "/", [0, 1],
1716
+ :tSTRING_CONTENT, "regex\\cxxx", [1, 11],
1717
+ :tSTRING_END, "/", [11, 12],
1718
+ :tREGEXP_OPT, "", [12, 12])
1705
1719
  end
1706
1720
 
1707
1721
  def test_regexp_escape_c_backslash
1708
1722
  assert_scanned('/regex\\c\\n/',
1709
- :tREGEXP_BEG, "/",
1710
- :tSTRING_CONTENT, "regex\\c\\n",
1711
- :tSTRING_END, "/",
1712
- :tREGEXP_OPT, "")
1723
+ :tREGEXP_BEG, "/", [0, 1],
1724
+ :tSTRING_CONTENT, "regex\\c\\n", [1, 10],
1725
+ :tSTRING_END, "/", [10, 11],
1726
+ :tREGEXP_OPT, "", [11, 11])
1713
1727
  end
1714
1728
 
1715
1729
  def test_regexp_escape_chars
1716
1730
  assert_scanned('/re\\tge\\nxp/',
1717
- :tREGEXP_BEG, "/",
1718
- :tSTRING_CONTENT, "re\\tge\\nxp",
1719
- :tSTRING_END, "/",
1720
- :tREGEXP_OPT, "")
1731
+ :tREGEXP_BEG, "/", [0, 1],
1732
+ :tSTRING_CONTENT, "re\\tge\\nxp", [1, 11],
1733
+ :tSTRING_END, "/", [11, 12],
1734
+ :tREGEXP_OPT, "", [12, 12])
1721
1735
  end
1722
1736
 
1723
1737
  def test_regexp_escape_double_backslash
1724
1738
  assert_scanned('/[\\/\\\\]$/',
1725
- :tREGEXP_BEG, "/",
1726
- :tSTRING_CONTENT,'[/\\\\]$',
1727
- :tSTRING_END, "/",
1728
- :tREGEXP_OPT, "")
1739
+ :tREGEXP_BEG, "/", [0, 1],
1740
+ :tSTRING_CONTENT,'[/\\\\]$', [1, 8],
1741
+ :tSTRING_END, "/", [8, 9],
1742
+ :tREGEXP_OPT, "", [9, 9])
1729
1743
  end
1730
1744
 
1731
1745
  def test_regexp_escape_hex
1732
1746
  assert_scanned('/regex\\x61xp/',
1733
- :tREGEXP_BEG, "/",
1734
- :tSTRING_CONTENT, "regex\\x61xp",
1735
- :tSTRING_END, "/",
1736
- :tREGEXP_OPT, "")
1747
+ :tREGEXP_BEG, "/", [0, 1],
1748
+ :tSTRING_CONTENT, "regex\\x61xp", [1, 12],
1749
+ :tSTRING_END, "/", [12, 13],
1750
+ :tREGEXP_OPT, "", [13, 13])
1737
1751
  end
1738
1752
 
1739
1753
  def test_regexp_escape_hex_bad
1740
- refute_scanned '/regex\\xzxp/', :tREGEXP_BEG, "/"
1754
+ refute_scanned '/regex\\xzxp/', :tREGEXP_BEG, "/", [0, 1]
1741
1755
  end
1742
1756
 
1743
1757
  def test_regexp_escape_hex_one
1744
1758
  assert_scanned('/^[\\xd\\xa]{2}/on',
1745
- :tREGEXP_BEG, '/',
1746
- :tSTRING_CONTENT, '^[\\xd\\xa]{2}',
1747
- :tSTRING_END, "/",
1748
- :tREGEXP_OPT, 'on')
1759
+ :tREGEXP_BEG, '/', [0, 1],
1760
+ :tSTRING_CONTENT, '^[\\xd\\xa]{2}', [1, 13],
1761
+ :tSTRING_END, "/", [13, 14],
1762
+ :tREGEXP_OPT, 'on', [14, 16])
1749
1763
  end
1750
1764
 
1751
1765
  def test_regexp_escape_oct1
1752
1766
  assert_scanned('/regex\\0xp/',
1753
- :tREGEXP_BEG, "/",
1754
- :tSTRING_CONTENT, "regex\\0xp",
1755
- :tSTRING_END, "/",
1756
- :tREGEXP_OPT, "")
1767
+ :tREGEXP_BEG, "/", [0, 1],
1768
+ :tSTRING_CONTENT, "regex\\0xp", [1, 10],
1769
+ :tSTRING_END, "/", [10, 11],
1770
+ :tREGEXP_OPT, "", [11, 11])
1757
1771
  end
1758
1772
 
1759
1773
  def test_regexp_escape_oct2
1760
1774
  assert_scanned('/regex\\07xp/',
1761
- :tREGEXP_BEG, "/",
1762
- :tSTRING_CONTENT, "regex\\07xp",
1763
- :tSTRING_END, "/",
1764
- :tREGEXP_OPT, "")
1775
+ :tREGEXP_BEG, "/", [0, 1],
1776
+ :tSTRING_CONTENT, "regex\\07xp", [1, 11],
1777
+ :tSTRING_END, "/", [11, 12],
1778
+ :tREGEXP_OPT, "", [12, 12])
1765
1779
  end
1766
1780
 
1767
1781
  def test_regexp_escape_oct3
1768
1782
  assert_scanned('/regex\\10142/',
1769
- :tREGEXP_BEG, "/",
1770
- :tSTRING_CONTENT, "regex\\10142",
1771
- :tSTRING_END, "/",
1772
- :tREGEXP_OPT, "")
1783
+ :tREGEXP_BEG, "/", [0, 1],
1784
+ :tSTRING_CONTENT, "regex\\10142", [1, 12],
1785
+ :tSTRING_END, "/", [12, 13],
1786
+ :tREGEXP_OPT, "", [13, 13])
1773
1787
  end
1774
1788
 
1775
1789
  def test_regexp_escape_return
1776
1790
  assert_scanned("/regex\\\nregex/",
1777
- :tREGEXP_BEG, "/",
1778
- :tSTRING_CONTENT, "regexregex",
1779
- :tSTRING_END, "/",
1780
- :tREGEXP_OPT, "")
1791
+ :tREGEXP_BEG, "/", [0, 1],
1792
+ :tSTRING_CONTENT, "regexregex", [1, 13],
1793
+ :tSTRING_END, "/", [13, 14],
1794
+ :tREGEXP_OPT, "", [14, 14])
1781
1795
  end
1782
1796
 
1783
1797
  def test_regexp_escape_delimiter_meta
1784
1798
  assert_scanned("%r(\\))",
1785
- :tREGEXP_BEG, "%r(",
1786
- :tSTRING_CONTENT, "\\)",
1787
- :tSTRING_END, ")",
1788
- :tREGEXP_OPT, "")
1799
+ :tREGEXP_BEG, "%r(", [0, 3],
1800
+ :tSTRING_CONTENT, "\\)", [3, 5],
1801
+ :tSTRING_END, ")", [5, 6],
1802
+ :tREGEXP_OPT, "", [6, 6])
1789
1803
  end
1790
1804
 
1791
1805
  def test_regexp_escape_delimiter_nonmeta
1792
1806
  assert_scanned("%r'\\''",
1793
- :tREGEXP_BEG, "%r'",
1794
- :tSTRING_CONTENT, "'",
1795
- :tSTRING_END, "'",
1796
- :tREGEXP_OPT, "")
1807
+ :tREGEXP_BEG, "%r'", [0, 3],
1808
+ :tSTRING_CONTENT, "'", [3, 5],
1809
+ :tSTRING_END, "'", [5, 6],
1810
+ :tREGEXP_OPT, "", [6, 6])
1797
1811
  end
1798
1812
 
1799
1813
  def test_regexp_escape_other_meta
1800
1814
  assert_scanned("/\\.\\$\\*\\+\\.\\?\\|/",
1801
- :tREGEXP_BEG, "/",
1802
- :tSTRING_CONTENT, "\\.\\$\\*\\+\\.\\?\\|",
1803
- :tSTRING_END, "/",
1804
- :tREGEXP_OPT, "")
1815
+ :tREGEXP_BEG, "/", [0, 1],
1816
+ :tSTRING_CONTENT, "\\.\\$\\*\\+\\.\\?\\|", [1, 15],
1817
+ :tSTRING_END, "/", [15, 16],
1818
+ :tREGEXP_OPT, "", [16, 16])
1805
1819
  end
1806
1820
 
1807
1821
  def test_regexp_nm
1808
1822
  assert_scanned("/.*/nm",
1809
- :tREGEXP_BEG, "/",
1810
- :tSTRING_CONTENT, ".*",
1811
- :tSTRING_END, "/",
1812
- :tREGEXP_OPT, "nm")
1823
+ :tREGEXP_BEG, "/", [0, 1],
1824
+ :tSTRING_CONTENT, ".*", [1, 3],
1825
+ :tSTRING_END, "/", [3, 4],
1826
+ :tREGEXP_OPT, "nm", [4, 6])
1813
1827
  end
1814
1828
 
1815
1829
  def test_rparen
1816
- assert_scanned ")", :tRPAREN, ")"
1830
+ assert_scanned ")", :tRPAREN, ")", [0, 1]
1817
1831
  end
1818
1832
 
1819
1833
  def test_rshft
1820
1834
  assert_scanned("a >> 2",
1821
- :tIDENTIFIER, "a",
1822
- :tRSHFT, ">>",
1823
- :tINTEGER, 2)
1835
+ :tIDENTIFIER, "a", [0, 1],
1836
+ :tRSHFT, ">>", [2, 4],
1837
+ :tINTEGER, 2, [5, 6])
1824
1838
  end
1825
1839
 
1826
1840
  def test_rshft_equals
1827
1841
  assert_scanned("a >>= 2",
1828
- :tIDENTIFIER, "a",
1829
- :tOP_ASGN, ">>",
1830
- :tINTEGER, 2)
1842
+ :tIDENTIFIER, "a", [0, 1],
1843
+ :tOP_ASGN, ">>", [2, 5],
1844
+ :tINTEGER, 2, [6, 7])
1831
1845
  end
1832
1846
 
1833
1847
  def test_star
1834
1848
  assert_scanned("a * ",
1835
- :tIDENTIFIER, "a",
1836
- :tSTAR2, "*")
1849
+ :tIDENTIFIER, "a", [0, 1],
1850
+ :tSTAR2, "*", [2, 3])
1837
1851
 
1838
1852
  assert_equal :expr_beg, @lex.state
1839
1853
  end
1840
1854
 
1841
1855
  def test_star2
1842
1856
  assert_scanned("a ** ",
1843
- :tIDENTIFIER, "a",
1844
- :tPOW, "**")
1857
+ :tIDENTIFIER, "a", [0, 1],
1858
+ :tPOW, "**", [2, 4])
1845
1859
 
1846
1860
  assert_equal :expr_beg, @lex.state
1847
1861
  end
1848
1862
 
1849
1863
  def test_star2_equals
1850
1864
  assert_scanned("a **= ",
1851
- :tIDENTIFIER, "a",
1852
- :tOP_ASGN, "**")
1865
+ :tIDENTIFIER, "a", [0, 1],
1866
+ :tOP_ASGN, "**", [2, 5])
1853
1867
 
1854
1868
  assert_equal :expr_beg, @lex.state
1855
1869
  end
1856
1870
 
1857
1871
  def test_star2_beg
1858
1872
  assert_scanned("** ",
1859
- :tDSTAR, "**")
1873
+ :tDSTAR, "**", [0, 2])
1860
1874
 
1861
1875
  assert_equal :expr_beg, @lex.state
1862
1876
  end
@@ -1865,8 +1879,8 @@ class TestLexer < Minitest::Test
1865
1879
  @lex.state = :expr_arg
1866
1880
 
1867
1881
  assert_scanned(" *a",
1868
- :tSTAR, "*",
1869
- :tIDENTIFIER, "a")
1882
+ :tSTAR, "*", [1, 2],
1883
+ :tIDENTIFIER, "a", [2, 3])
1870
1884
 
1871
1885
  assert_equal :expr_arg, @lex.state
1872
1886
  end
@@ -1875,8 +1889,8 @@ class TestLexer < Minitest::Test
1875
1889
  @lex.state = :expr_beg
1876
1890
 
1877
1891
  assert_scanned("*a",
1878
- :tSTAR, "*",
1879
- :tIDENTIFIER, "a")
1892
+ :tSTAR, "*", [0, 1],
1893
+ :tIDENTIFIER, "a", [1, 2])
1880
1894
 
1881
1895
  assert_equal :expr_arg, @lex.state
1882
1896
  end
@@ -1885,454 +1899,454 @@ class TestLexer < Minitest::Test
1885
1899
  @lex.state = :expr_fname
1886
1900
 
1887
1901
  assert_scanned("*a",
1888
- :tSTAR2, "*",
1889
- :tIDENTIFIER, "a")
1902
+ :tSTAR2, "*", [0, 1],
1903
+ :tIDENTIFIER, "a", [1, 2])
1890
1904
 
1891
1905
  assert_equal :expr_arg, @lex.state
1892
1906
  end
1893
1907
 
1894
1908
  def test_star_equals
1895
1909
  assert_scanned("a *= ",
1896
- :tIDENTIFIER, "a",
1897
- :tOP_ASGN, "*")
1910
+ :tIDENTIFIER, "a", [0, 1],
1911
+ :tOP_ASGN, "*", [2, 4])
1898
1912
 
1899
1913
  assert_equal :expr_beg, @lex.state
1900
1914
  end
1901
1915
 
1902
1916
  def test_string_bad_eos
1903
1917
  refute_scanned('%',
1904
- :tSTRING_BEG, '%')
1918
+ :tSTRING_BEG, '%', [0, 1])
1905
1919
  end
1906
1920
 
1907
1921
  def test_string_bad_eos_quote
1908
1922
  refute_scanned('%{nest',
1909
- :tSTRING_BEG, '%}')
1923
+ :tSTRING_BEG, '%}', [0, 2])
1910
1924
  end
1911
1925
 
1912
1926
  def test_string_double
1913
1927
  assert_scanned('"string"',
1914
- :tSTRING, "string")
1928
+ :tSTRING, "string", [0, 8])
1915
1929
  end
1916
1930
 
1917
1931
  def test_string_double_escape_C
1918
1932
  assert_scanned('"\\C-a"',
1919
- :tSTRING, "\001")
1933
+ :tSTRING, "\001", [0, 6])
1920
1934
  end
1921
1935
 
1922
1936
  def test_string_double_escape_C_backslash
1923
1937
  assert_scanned('"\\C-\\\\"',
1924
- :tSTRING, "\034")
1938
+ :tSTRING, "\034", [0, 7])
1925
1939
  end
1926
1940
 
1927
1941
  def test_string_double_escape_C_escape
1928
1942
  assert_scanned('"\\C-\\M-a"',
1929
- :tSTRING, "\201")
1943
+ :tSTRING, "\201", [0, 9])
1930
1944
  end
1931
1945
 
1932
1946
  def test_string_double_escape_C_question
1933
1947
  assert_scanned('"\\C-?"',
1934
- :tSTRING, "\177")
1948
+ :tSTRING, "\177", [0, 6])
1935
1949
  end
1936
1950
 
1937
1951
  def test_string_double_escape_M
1938
1952
  assert_scanned('"\\M-a"',
1939
- :tSTRING, "\341")
1953
+ :tSTRING, "\341", [0, 6])
1940
1954
  end
1941
1955
 
1942
1956
  def test_string_double_escape_M_backslash
1943
1957
  assert_scanned('"\\M-\\\\"',
1944
- :tSTRING, "\334")
1958
+ :tSTRING, "\334", [0, 7])
1945
1959
  end
1946
1960
 
1947
1961
  def test_string_double_escape_M_escape
1948
1962
  assert_scanned('"\\M-\\C-a"',
1949
- :tSTRING, "\201")
1963
+ :tSTRING, "\201", [0, 9])
1950
1964
  end
1951
1965
 
1952
1966
  def test_string_double_escape_bs1
1953
1967
  assert_scanned('"a\\a\\a"',
1954
- :tSTRING, "a\a\a")
1968
+ :tSTRING, "a\a\a", [0, 7])
1955
1969
  end
1956
1970
 
1957
1971
  def test_string_double_escape_bs2
1958
1972
  assert_scanned('"a\\\\a"',
1959
- :tSTRING, "a\\a")
1973
+ :tSTRING, "a\\a", [0, 6])
1960
1974
  end
1961
1975
 
1962
1976
  def test_string_double_escape_c
1963
1977
  assert_scanned('"\\ca"',
1964
- :tSTRING, "\001")
1978
+ :tSTRING, "\001", [0, 5])
1965
1979
  end
1966
1980
 
1967
1981
  def test_string_double_escape_c_escape
1968
1982
  assert_scanned('"\\c\\M-a"',
1969
- :tSTRING, "\201")
1983
+ :tSTRING, "\201", [0, 8])
1970
1984
  end
1971
1985
 
1972
1986
  def test_string_double_escape_c_question
1973
1987
  assert_scanned('"\\c?"',
1974
- :tSTRING, "\177")
1988
+ :tSTRING, "\177", [0, 5])
1975
1989
  end
1976
1990
 
1977
1991
  def test_string_double_escape_chars
1978
1992
  assert_scanned('"s\\tri\\ng"',
1979
- :tSTRING, "s\tri\ng")
1993
+ :tSTRING, "s\tri\ng", [0, 10])
1980
1994
  end
1981
1995
 
1982
1996
  def test_string_double_escape_hex
1983
1997
  assert_scanned('"n = \\x61\\x62\\x63"',
1984
- :tSTRING, "n = abc")
1998
+ :tSTRING, "n = abc", [0, 18])
1985
1999
  end
1986
2000
 
1987
2001
  def test_string_double_escape_octal
1988
2002
  assert_scanned('"n = \\101\\102\\103"',
1989
- :tSTRING, "n = ABC")
2003
+ :tSTRING, "n = ABC", [0, 18])
1990
2004
  end
1991
2005
 
1992
2006
  def test_string_double_escape_octal_wrap
1993
2007
  assert_scanned('"\\753"',
1994
- :tSTRING, "\xEB")
2008
+ :tSTRING, "\xEB", [0, 6])
1995
2009
  end
1996
2010
 
1997
2011
  def test_string_double_interp
1998
2012
  assert_scanned("\"blah #x a \#@a b \#$b c \#{3} # \"",
1999
- :tSTRING_BEG, "\"",
2000
- :tSTRING_CONTENT, "blah #x a ",
2001
- :tSTRING_DVAR, nil,
2002
- :tIVAR, "@a",
2003
- :tSTRING_CONTENT, " b ",
2004
- :tSTRING_DVAR, nil,
2005
- :tGVAR, "$b",
2006
- :tSTRING_CONTENT, " c ",
2007
- :tSTRING_DBEG, '#{',
2008
- :tINTEGER, 3,
2009
- :tRCURLY, "}",
2010
- :tSTRING_CONTENT, " # ",
2011
- :tSTRING_END, "\"")
2013
+ :tSTRING_BEG, "\"", [0, 1],
2014
+ :tSTRING_CONTENT, "blah #x a ", [1, 11],
2015
+ :tSTRING_DVAR, nil, [11, 12],
2016
+ :tIVAR, "@a", [12, 14],
2017
+ :tSTRING_CONTENT, " b ", [14, 17],
2018
+ :tSTRING_DVAR, nil, [17, 18],
2019
+ :tGVAR, "$b", [18, 20],
2020
+ :tSTRING_CONTENT, " c ", [20, 23],
2021
+ :tSTRING_DBEG, '#{', [23, 25],
2022
+ :tINTEGER, 3, [25, 26],
2023
+ :tRCURLY, "}", [26, 27],
2024
+ :tSTRING_CONTENT, " # ", [27, 30],
2025
+ :tSTRING_END, "\"", [30, 31])
2012
2026
  end
2013
2027
 
2014
2028
  def test_string_double_interp_label
2015
2029
  assert_scanned('"#{foo:bar}"',
2016
- :tSTRING_BEG, '"',
2017
- :tSTRING_DBEG, '#{',
2018
- :tIDENTIFIER, 'foo',
2019
- :tSYMBOL, 'bar',
2020
- :tRCURLY, '}',
2021
- :tSTRING_END, '"')
2030
+ :tSTRING_BEG, '"', [0, 1],
2031
+ :tSTRING_DBEG, '#{', [1, 3],
2032
+ :tIDENTIFIER, 'foo', [3, 6],
2033
+ :tSYMBOL, 'bar', [6, 10],
2034
+ :tRCURLY, '}', [10, 11],
2035
+ :tSTRING_END, '"', [11, 12])
2022
2036
  end
2023
2037
 
2024
2038
  def test_string_double_nested_curlies
2025
2039
  assert_scanned('%{nest{one{two}one}nest}',
2026
- :tSTRING_BEG, '%{',
2027
- :tSTRING_CONTENT, "nest{one{two}one}nest",
2028
- :tSTRING_END, '}')
2040
+ :tSTRING_BEG, '%{', [0, 2],
2041
+ :tSTRING_CONTENT, "nest{one{two}one}nest", [2, 23],
2042
+ :tSTRING_END, '}', [23, 24])
2029
2043
  end
2030
2044
 
2031
2045
  def test_string_double_no_interp
2032
2046
  assert_scanned("\"# blah\"", # pound first
2033
- :tSTRING, "# blah")
2047
+ :tSTRING, "# blah", [0, 8])
2034
2048
 
2035
2049
  assert_scanned("\"blah # blah\"", # pound not first
2036
- :tSTRING, "blah # blah")
2050
+ :tSTRING, "blah # blah", [0, 13])
2037
2051
  end
2038
2052
 
2039
2053
  def test_string_escape_x_single
2040
2054
  assert_scanned('"\\x0"',
2041
- :tSTRING, "\000")
2055
+ :tSTRING, "\000", [0, 5])
2042
2056
  end
2043
2057
 
2044
2058
  def test_string_pct_Q
2045
2059
  assert_scanned("%Q[s1 s2]",
2046
- :tSTRING_BEG, '%Q[',
2047
- :tSTRING_CONTENT, "s1 s2",
2048
- :tSTRING_END, ']')
2060
+ :tSTRING_BEG, '%Q[', [0, 3],
2061
+ :tSTRING_CONTENT, "s1 s2", [3, 8],
2062
+ :tSTRING_END, ']', [8, 9])
2049
2063
  end
2050
2064
 
2051
2065
  def test_string_pct_W
2052
2066
  assert_scanned("%W[s1 s2\ns3]",
2053
- :tWORDS_BEG, "%W[",
2054
- :tSTRING_CONTENT, "s1",
2055
- :tSPACE, nil,
2056
- :tSTRING_CONTENT, "s2",
2057
- :tSPACE, nil,
2058
- :tSTRING_CONTENT, "s3",
2059
- :tSPACE, nil,
2060
- :tSTRING_END, ']')
2067
+ :tWORDS_BEG, "%W[", [0, 3],
2068
+ :tSTRING_CONTENT, "s1", [3, 5],
2069
+ :tSPACE, nil, [5, 6],
2070
+ :tSTRING_CONTENT, "s2", [6, 8],
2071
+ :tSPACE, nil, [8, 9],
2072
+ :tSTRING_CONTENT, "s3", [9, 11],
2073
+ :tSPACE, nil, [11, 11],
2074
+ :tSTRING_END, ']', [11, 12])
2061
2075
  end
2062
2076
 
2063
2077
  def test_string_pct_W_bs_nl
2064
2078
  assert_scanned("%W[s1 \\\ns2]",
2065
- :tWORDS_BEG, "%W[",
2066
- :tSTRING_CONTENT, "s1",
2067
- :tSPACE, nil,
2068
- :tSTRING_CONTENT, "\ns2",
2069
- :tSPACE, nil,
2070
- :tSTRING_END, ']')
2079
+ :tWORDS_BEG, "%W[", [0, 3],
2080
+ :tSTRING_CONTENT, "s1", [3, 5],
2081
+ :tSPACE, nil, [5, 6],
2082
+ :tSTRING_CONTENT, "\ns2", [6, 10],
2083
+ :tSPACE, nil, [10, 10],
2084
+ :tSTRING_END, ']', [10, 11])
2071
2085
  end
2072
2086
 
2073
2087
  def test_string_pct_W_interp
2074
2088
  assert_scanned('%W[#{1}#{2} #@a]',
2075
- :tWORDS_BEG, '%W[',
2076
- :tSTRING_DBEG, '#{',
2077
- :tINTEGER, 1,
2078
- :tRCURLY, '}',
2079
- :tSTRING_DBEG, '#{',
2080
- :tINTEGER, 2,
2081
- :tRCURLY, '}',
2082
- :tSPACE, nil,
2083
- :tSTRING_DVAR, nil,
2084
- :tIVAR, '@a',
2085
- :tSPACE, nil,
2086
- :tSTRING_END, ']')
2089
+ :tWORDS_BEG, '%W[', [0, 3],
2090
+ :tSTRING_DBEG, '#{', [3, 5],
2091
+ :tINTEGER, 1, [5, 6],
2092
+ :tRCURLY, '}', [6, 7],
2093
+ :tSTRING_DBEG, '#{', [7, 9],
2094
+ :tINTEGER, 2, [9, 10],
2095
+ :tRCURLY, '}', [10, 11],
2096
+ :tSPACE, nil, [11, 12],
2097
+ :tSTRING_DVAR, nil, [12, 13],
2098
+ :tIVAR, '@a', [13, 15],
2099
+ :tSPACE, nil, [15, 15],
2100
+ :tSTRING_END, ']', [15, 16])
2087
2101
  end
2088
2102
 
2089
2103
  def test_string_pct_I
2090
2104
  assert_scanned("%I(s1 s2)",
2091
- :tSYMBOLS_BEG, "%I(",
2092
- :tSTRING_CONTENT, "s1",
2093
- :tSPACE, nil,
2094
- :tSTRING_CONTENT, "s2",
2095
- :tSPACE, nil,
2096
- :tSTRING_END, ')')
2105
+ :tSYMBOLS_BEG, "%I(", [0, 3],
2106
+ :tSTRING_CONTENT, "s1", [3, 5],
2107
+ :tSPACE, nil, [5, 6],
2108
+ :tSTRING_CONTENT, "s2", [6, 8],
2109
+ :tSPACE, nil, [8, 8],
2110
+ :tSTRING_END, ')', [8, 9])
2097
2111
  end
2098
2112
 
2099
2113
  def test_string_pct_angle
2100
2114
  assert_scanned("%<blah>",
2101
- :tSTRING_BEG, '%<',
2102
- :tSTRING_CONTENT, "blah",
2103
- :tSTRING_END, '>')
2115
+ :tSTRING_BEG, '%<', [0, 2],
2116
+ :tSTRING_CONTENT, "blah", [2, 6],
2117
+ :tSTRING_END, '>', [6, 7])
2104
2118
  end
2105
2119
 
2106
2120
  def test_string_pct_pct
2107
2121
  assert_scanned("%%blah%",
2108
- :tSTRING_BEG, '%%',
2109
- :tSTRING_CONTENT, "blah",
2110
- :tSTRING_END, '%')
2122
+ :tSTRING_BEG, '%%', [0, 2],
2123
+ :tSTRING_CONTENT, "blah", [2, 6],
2124
+ :tSTRING_END, '%', [6, 7])
2111
2125
  end
2112
2126
 
2113
2127
  def test_string_pct_w
2114
2128
  assert_scanned("%w[s1 s2 ]",
2115
- :tQWORDS_BEG, "%w[",
2116
- :tSTRING_CONTENT, "s1",
2117
- :tSPACE, nil,
2118
- :tSTRING_CONTENT, "s2",
2119
- :tSPACE, nil,
2120
- :tSTRING_END, "]")
2129
+ :tQWORDS_BEG, "%w[", [0, 3],
2130
+ :tSTRING_CONTENT, "s1", [3, 5],
2131
+ :tSPACE, nil, [5, 6],
2132
+ :tSTRING_CONTENT, "s2", [6, 8],
2133
+ :tSPACE, nil, [8, 9],
2134
+ :tSTRING_END, "]", [9, 10])
2121
2135
  end
2122
2136
 
2123
2137
  def test_string_pct_w_incomplete
2124
2138
  refute_scanned("%w[s1 ",
2125
- :tQWORDS_BEG, "%w[",
2126
- :tSTRING_CONTENT, "s1",
2127
- :tSPACE, nil)
2139
+ :tQWORDS_BEG, "%w[", [0, 3],
2140
+ :tSTRING_CONTENT, "s1", [3, 5],
2141
+ :tSPACE, nil, [5, 6])
2128
2142
  end
2129
2143
 
2130
2144
  def test_string_pct_w_bs_nl
2131
2145
  assert_scanned("%w[s1 \\\ns2]",
2132
- :tQWORDS_BEG, "%w[",
2133
- :tSTRING_CONTENT, "s1",
2134
- :tSPACE, nil,
2135
- :tSTRING_CONTENT, "\ns2",
2136
- :tSPACE, nil,
2137
- :tSTRING_END, ']')
2146
+ :tQWORDS_BEG, "%w[", [0, 3],
2147
+ :tSTRING_CONTENT, "s1", [3, 5],
2148
+ :tSPACE, nil, [5, 6],
2149
+ :tSTRING_CONTENT, "\ns2", [6, 10],
2150
+ :tSPACE, nil, [10, 10],
2151
+ :tSTRING_END, ']', [10, 11])
2138
2152
  end
2139
2153
 
2140
2154
  def test_string_pct_w_bs_sp
2141
2155
  assert_scanned("%w[s\\ 1 s\\ 2]",
2142
- :tQWORDS_BEG, "%w[",
2143
- :tSTRING_CONTENT, "s 1",
2144
- :tSPACE, nil,
2145
- :tSTRING_CONTENT, "s 2",
2146
- :tSPACE, nil,
2147
- :tSTRING_END, ']')
2156
+ :tQWORDS_BEG, "%w[", [0, 3],
2157
+ :tSTRING_CONTENT, "s 1", [3, 7],
2158
+ :tSPACE, nil, [7, 8],
2159
+ :tSTRING_CONTENT, "s 2", [8, 12],
2160
+ :tSPACE, nil, [12, 12],
2161
+ :tSTRING_END, ']', [12, 13])
2148
2162
  end
2149
2163
 
2150
2164
  def test_string_pct_w_tab
2151
2165
  assert_scanned("%w[abc\tdef]",
2152
- :tQWORDS_BEG, "%w[",
2153
- :tSTRING_CONTENT, "abc",
2154
- :tSPACE, nil,
2155
- :tSTRING_CONTENT, "def",
2156
- :tSPACE, nil,
2157
- :tSTRING_END, ']')
2166
+ :tQWORDS_BEG, "%w[", [0, 3],
2167
+ :tSTRING_CONTENT, "abc", [3, 6],
2168
+ :tSPACE, nil, [6, 7],
2169
+ :tSTRING_CONTENT, "def", [7, 10],
2170
+ :tSPACE, nil, [10, 10],
2171
+ :tSTRING_END, ']', [10, 11])
2158
2172
  end
2159
2173
 
2160
2174
  def test_string_pct_i
2161
2175
  assert_scanned("%i(s1 s2)",
2162
- :tQSYMBOLS_BEG, "%i(",
2163
- :tSTRING_CONTENT, "s1",
2164
- :tSPACE, nil,
2165
- :tSTRING_CONTENT, "s2",
2166
- :tSPACE, nil,
2167
- :tSTRING_END, ')')
2176
+ :tQSYMBOLS_BEG, "%i(", [0, 3],
2177
+ :tSTRING_CONTENT, "s1", [3, 5],
2178
+ :tSPACE, nil, [5, 6],
2179
+ :tSTRING_CONTENT, "s2", [6, 8],
2180
+ :tSPACE, nil, [8, 8],
2181
+ :tSTRING_END, ')', [8, 9])
2168
2182
  end
2169
2183
 
2170
2184
  def test_string_pct_backslash
2171
2185
  assert_scanned("%\\a\\",
2172
- :tSTRING_BEG, "%\\",
2173
- :tSTRING_CONTENT, "a",
2174
- :tSTRING_END, "\\")
2186
+ :tSTRING_BEG, "%\\", [0, 2],
2187
+ :tSTRING_CONTENT, "a", [2, 3],
2188
+ :tSTRING_END, "\\", [3, 4])
2175
2189
  end
2176
2190
 
2177
2191
  def test_string_pct_backslash_with_bad_escape
2178
2192
  # No escapes are allowed in a backslash-delimited string
2179
2193
  refute_scanned("%\\a\\n\\",
2180
- :tSTRING_BEG, "%\\",
2181
- :tSTRING_CONTENT, "a",
2182
- :tSTRING_END, "\\",
2183
- :tIDENTIFIER, "n")
2194
+ :tSTRING_BEG, "%\\", [0, 2],
2195
+ :tSTRING_CONTENT, "a", [2, 3],
2196
+ :tSTRING_END, "\\", [3, 4],
2197
+ :tIDENTIFIER, "n", [4, 5])
2184
2198
  end
2185
2199
 
2186
2200
  def test_string_pct_intertwined_with_heredoc
2187
2201
  assert_scanned("<<-foo + %\\a\nbar\nfoo\nb\\",
2188
- :tSTRING_BEG, "<<\"",
2189
- :tSTRING_CONTENT, "bar\n",
2190
- :tSTRING_END, "foo",
2191
- :tPLUS, "+",
2192
- :tSTRING_BEG, "%\\",
2193
- :tSTRING_CONTENT, "a\n",
2194
- :tSTRING_CONTENT, "b",
2195
- :tSTRING_END, "\\")
2202
+ :tSTRING_BEG, "<<\"", [0, 6],
2203
+ :tSTRING_CONTENT, "bar\n", [13, 17],
2204
+ :tSTRING_END, "foo", [17, 20],
2205
+ :tPLUS, "+", [7, 8],
2206
+ :tSTRING_BEG, "%\\", [9, 11],
2207
+ :tSTRING_CONTENT, "a\n", [11, 13],
2208
+ :tSTRING_CONTENT, "b", [21, 22],
2209
+ :tSTRING_END, "\\", [22, 23])
2196
2210
  end
2197
2211
 
2198
2212
  def test_string_pct_q_backslash
2199
2213
  assert_scanned("%q\\a\\",
2200
- :tSTRING_BEG, "%q\\",
2201
- :tSTRING_CONTENT, "a",
2202
- :tSTRING_END, "\\")
2214
+ :tSTRING_BEG, "%q\\", [0, 3],
2215
+ :tSTRING_CONTENT, "a", [3, 4],
2216
+ :tSTRING_END, "\\", [4, 5])
2203
2217
  end
2204
2218
 
2205
2219
  def test_string_pct_Q_backslash
2206
2220
  assert_scanned("%Q\\a\\",
2207
- :tSTRING_BEG, "%Q\\",
2208
- :tSTRING_CONTENT, "a",
2209
- :tSTRING_END, "\\")
2221
+ :tSTRING_BEG, "%Q\\", [0, 3],
2222
+ :tSTRING_CONTENT, "a", [3, 4],
2223
+ :tSTRING_END, "\\", [4, 5])
2210
2224
  end
2211
2225
 
2212
2226
  def test_string_single
2213
2227
  assert_scanned("'string'",
2214
- :tSTRING, "string")
2228
+ :tSTRING, "string", [0, 8])
2215
2229
  end
2216
2230
 
2217
2231
  def test_string_single_escape_chars
2218
2232
  assert_scanned("'s\\tri\\ng'",
2219
- :tSTRING, "s\\tri\\ng")
2233
+ :tSTRING, "s\\tri\\ng", [0, 10])
2220
2234
  end
2221
2235
 
2222
2236
  def test_string_single_nl
2223
2237
  assert_scanned("'blah\\\nblah'",
2224
- :tSTRING_BEG, "'",
2225
- :tSTRING_CONTENT, "blah\\\n",
2226
- :tSTRING_CONTENT, "blah",
2227
- :tSTRING_END, "'")
2238
+ :tSTRING_BEG, "'", [0, 1],
2239
+ :tSTRING_CONTENT, "blah\\\n", [1, 7],
2240
+ :tSTRING_CONTENT, "blah", [7, 11],
2241
+ :tSTRING_END, "'", [11, 12])
2228
2242
  end
2229
2243
 
2230
2244
  def test_symbol
2231
2245
  assert_scanned(":symbol",
2232
- :tSYMBOL, "symbol")
2246
+ :tSYMBOL, "symbol", [0, 7])
2233
2247
  end
2234
2248
 
2235
2249
  def test_symbol_double
2236
2250
  assert_scanned(":\"symbol\"",
2237
- :tSYMBEG, ":\"",
2238
- :tSTRING_CONTENT, "symbol",
2239
- :tSTRING_END, "\"")
2251
+ :tSYMBEG, ":\"", [0, 2],
2252
+ :tSTRING_CONTENT, "symbol", [2, 8],
2253
+ :tSTRING_END, "\"", [8, 9])
2240
2254
  end
2241
2255
 
2242
2256
  def test_symbol_single
2243
2257
  assert_scanned(":'symbol'",
2244
- :tSYMBEG, ":'",
2245
- :tSTRING_CONTENT, "symbol",
2246
- :tSTRING_END, "'")
2258
+ :tSYMBEG, ":'", [0, 2],
2259
+ :tSTRING_CONTENT, "symbol", [2, 8],
2260
+ :tSTRING_END, "'", [8, 9])
2247
2261
  end
2248
2262
 
2249
2263
  def test_ternary
2250
2264
  assert_scanned("a ? b : c",
2251
- :tIDENTIFIER, "a",
2252
- :tEH, "?",
2253
- :tIDENTIFIER, "b",
2254
- :tCOLON, ":",
2255
- :tIDENTIFIER, "c")
2265
+ :tIDENTIFIER, "a", [0, 1],
2266
+ :tEH, "?", [2, 3],
2267
+ :tIDENTIFIER, "b", [4, 5],
2268
+ :tCOLON, ":", [6, 7],
2269
+ :tIDENTIFIER, "c", [8, 9])
2256
2270
 
2257
2271
  assert_scanned("a ?b : c",
2258
- :tIDENTIFIER, "a",
2259
- :tINTEGER, 98,
2260
- :tCOLON, ":",
2261
- :tIDENTIFIER, "c")
2272
+ :tIDENTIFIER, "a", [0, 1],
2273
+ :tINTEGER, 98, [2, 4],
2274
+ :tCOLON, ":", [5, 6],
2275
+ :tIDENTIFIER, "c", [7, 8])
2262
2276
 
2263
2277
  assert_scanned("a ?bb : c", # GAH! MATZ!!!
2264
- :tIDENTIFIER, "a",
2265
- :tEH, "?",
2266
- :tIDENTIFIER, "bb",
2267
- :tCOLON, ":",
2268
- :tIDENTIFIER, "c")
2278
+ :tIDENTIFIER, "a", [0, 1],
2279
+ :tEH, "?", [2, 3],
2280
+ :tIDENTIFIER, "bb", [3, 5],
2281
+ :tCOLON, ":", [6, 7],
2282
+ :tIDENTIFIER, "c", [8, 9])
2269
2283
 
2270
2284
  assert_scanned("42 ?", # 42 forces expr_end
2271
- :tINTEGER, 42,
2272
- :tEH, "?")
2285
+ :tINTEGER, 42, [0, 2],
2286
+ :tEH, "?", [3, 4])
2273
2287
  end
2274
2288
 
2275
2289
  def test_tilde
2276
- assert_scanned "~", :tTILDE, "~"
2290
+ assert_scanned "~", :tTILDE, "~", [0, 1]
2277
2291
  end
2278
2292
 
2279
2293
  def test_tilde_unary
2280
2294
  @lex.state = :expr_fname
2281
- assert_scanned "~@", :tTILDE, "~@"
2295
+ assert_scanned "~@", :tTILDE, "~@", [0, 2]
2282
2296
  end
2283
2297
 
2284
2298
  def test_uminus
2285
2299
  assert_scanned("-blah",
2286
- :tUMINUS, "-",
2287
- :tIDENTIFIER, "blah")
2300
+ :tUMINUS, "-", [0, 1],
2301
+ :tIDENTIFIER, "blah", [1, 5])
2288
2302
  end
2289
2303
 
2290
2304
  def test_underscore
2291
- assert_scanned("_var", :tIDENTIFIER, "_var")
2305
+ assert_scanned("_var", :tIDENTIFIER, "_var", [0, 4])
2292
2306
  end
2293
2307
 
2294
2308
  def test_underscore_end
2295
2309
  assert_scanned("__END__\n")
2296
2310
  assert_scanned("__END__")
2297
2311
  assert_scanned("__END__ foo",
2298
- :tIDENTIFIER, '__END__',
2299
- :tIDENTIFIER, 'foo')
2312
+ :tIDENTIFIER, '__END__', [0, 7],
2313
+ :tIDENTIFIER, 'foo', [8, 11])
2300
2314
  assert_scanned("__END__\rfoo",
2301
- :tIDENTIFIER, '__END__',
2302
- :tIDENTIFIER, 'foo')
2315
+ :tIDENTIFIER, '__END__', [0, 7],
2316
+ :tIDENTIFIER, 'foo', [8, 11])
2303
2317
  end
2304
2318
 
2305
2319
  def test_uplus
2306
2320
  assert_scanned("+blah",
2307
- :tUPLUS, "+",
2308
- :tIDENTIFIER, "blah")
2321
+ :tUPLUS, "+", [0, 1],
2322
+ :tIDENTIFIER, "blah", [1, 5])
2309
2323
  end
2310
2324
 
2311
2325
  def test_if_unless_mod
2312
2326
  assert_scanned("return if true unless false",
2313
- :kRETURN, "return",
2314
- :kIF_MOD, "if",
2315
- :kTRUE, "true",
2316
- :kUNLESS_MOD, "unless",
2317
- :kFALSE, "false")
2327
+ :kRETURN, "return", [0, 6],
2328
+ :kIF_MOD, "if", [7, 9],
2329
+ :kTRUE, "true", [10, 14],
2330
+ :kUNLESS_MOD, "unless", [15, 21],
2331
+ :kFALSE, "false", [22, 27])
2318
2332
  end
2319
2333
 
2320
2334
  def test_if_stmt
2321
2335
  assert_scanned("if true\n return end",
2322
- :kIF, "if",
2323
- :kTRUE, "true",
2324
- :tNL, nil,
2325
- :kRETURN, "return",
2326
- :kEND, "end")
2336
+ :kIF, "if", [0, 2],
2337
+ :kTRUE, "true", [3, 7],
2338
+ :tNL, nil, [7, 8],
2339
+ :kRETURN, "return", [9, 15],
2340
+ :kEND, "end", [16, 19])
2327
2341
  end
2328
2342
 
2329
2343
  def test_sclass_label
2330
2344
  setup_lexer 20
2331
2345
  assert_scanned("class << a:b",
2332
- :kCLASS, 'class',
2333
- :tLSHFT, '<<',
2334
- :tIDENTIFIER, 'a',
2335
- :tSYMBOL, 'b')
2346
+ :kCLASS, 'class', [0, 5],
2347
+ :tLSHFT, '<<', [6, 8],
2348
+ :tIDENTIFIER, 'a', [9, 10],
2349
+ :tSYMBOL, 'b', [10, 12])
2336
2350
  end
2337
2351
 
2338
2352
  def test_static_env
@@ -2341,10 +2355,10 @@ class TestLexer < Minitest::Test
2341
2355
 
2342
2356
  @lex.static_env = env
2343
2357
  assert_scanned("a [42]",
2344
- :tIDENTIFIER, "a",
2345
- :tLBRACK2, "[",
2346
- :tINTEGER, 42,
2347
- :tRBRACK, "]")
2358
+ :tIDENTIFIER, "a", [0, 1],
2359
+ :tLBRACK2, "[", [2, 3],
2360
+ :tINTEGER, 42, [3, 5],
2361
+ :tRBRACK, "]", [5, 6])
2348
2362
  end
2349
2363
 
2350
2364
  def test_int_suffix
@@ -2352,19 +2366,19 @@ class TestLexer < Minitest::Test
2352
2366
  setup_lexer version
2353
2367
 
2354
2368
  assert_scanned("42r",
2355
- :tINTEGER, 42,
2356
- :tIDENTIFIER, 'r')
2369
+ :tINTEGER, 42, [0, 2],
2370
+ :tIDENTIFIER, 'r', [2, 3])
2357
2371
 
2358
2372
  assert_scanned("42if",
2359
- :tINTEGER, 42,
2360
- :kIF_MOD, 'if')
2373
+ :tINTEGER, 42, [0, 2],
2374
+ :kIF_MOD, 'if', [2, 4])
2361
2375
  end
2362
2376
 
2363
2377
  setup_lexer 21
2364
2378
 
2365
- assert_scanned("42r", :tRATIONAL, Rational(42))
2366
- assert_scanned("42i", :tIMAGINARY, Complex(0, 42))
2367
- assert_scanned("42ri", :tIMAGINARY, Complex(0, Rational(42)))
2379
+ assert_scanned("42r", :tRATIONAL, Rational(42), [0, 3])
2380
+ assert_scanned("42i", :tIMAGINARY, Complex(0, 42), [0, 3])
2381
+ assert_scanned("42ri", :tIMAGINARY, Complex(0, Rational(42)), [0, 4])
2368
2382
  end
2369
2383
 
2370
2384
  def test_float_suffix
@@ -2372,16 +2386,16 @@ class TestLexer < Minitest::Test
2372
2386
  setup_lexer version
2373
2387
 
2374
2388
  assert_scanned("42.1r",
2375
- :tFLOAT, 42.1,
2376
- :tIDENTIFIER, 'r')
2389
+ :tFLOAT, 42.1, [0, 4],
2390
+ :tIDENTIFIER, 'r', [4, 5])
2377
2391
 
2378
2392
  assert_scanned("42.1if",
2379
- :tFLOAT, 42.1,
2380
- :kIF_MOD, 'if')
2393
+ :tFLOAT, 42.1, [0, 4],
2394
+ :kIF_MOD, 'if', [4, 6])
2381
2395
 
2382
2396
  assert_scanned("1e1r",
2383
- :tFLOAT, 1e1,
2384
- :tIDENTIFIER, 'r')
2397
+ :tFLOAT, 1e1, [0, 3],
2398
+ :tIDENTIFIER, 'r', [3, 4])
2385
2399
  end
2386
2400
 
2387
2401
  begin
@@ -2390,23 +2404,23 @@ class TestLexer < Minitest::Test
2390
2404
 
2391
2405
  setup_lexer 21
2392
2406
 
2393
- assert_scanned("42.1r", :tRATIONAL, Rational(421, 10))
2394
- assert_scanned("42.1i", :tIMAGINARY, Complex(0, 42.1))
2395
- assert_scanned("42.1ri", :tIMAGINARY, Complex(0, Rational(421, 10)))
2407
+ assert_scanned("42.1r", :tRATIONAL, Rational(421, 10), [0, 5])
2408
+ assert_scanned("42.1i", :tIMAGINARY, Complex(0, 42.1), [0, 5])
2409
+ assert_scanned("42.1ri", :tIMAGINARY, Complex(0, Rational(421, 10)), [0, 6])
2396
2410
  assert_scanned("42.1ir",
2397
- :tIMAGINARY, Complex(0, 42.1),
2398
- :tIDENTIFIER, 'r')
2411
+ :tIMAGINARY, Complex(0, 42.1), [0, 5],
2412
+ :tIDENTIFIER, 'r', [5, 6])
2399
2413
 
2400
- assert_scanned("1e1i", :tIMAGINARY, Complex(0, 1e1))
2414
+ assert_scanned("1e1i", :tIMAGINARY, Complex(0, 1e1), [0, 4])
2401
2415
  assert_scanned("1e1r",
2402
- :tFLOAT, 1e1,
2403
- :tIDENTIFIER, 'r')
2416
+ :tFLOAT, 1e1, [0, 3],
2417
+ :tIDENTIFIER, 'r', [3, 4])
2404
2418
  assert_scanned("1e1ri",
2405
- :tFLOAT, 1e1,
2406
- :tIDENTIFIER, 'ri')
2419
+ :tFLOAT, 1e1, [0, 3],
2420
+ :tIDENTIFIER, 'ri', [3, 5])
2407
2421
  assert_scanned("1e1ir",
2408
- :tIMAGINARY, Complex(0, 1e1),
2409
- :tIDENTIFIER, 'r')
2422
+ :tIMAGINARY, Complex(0, 1e1), [0, 4],
2423
+ :tIDENTIFIER, 'r', [4, 5])
2410
2424
  rescue NoMethodError
2411
2425
  # Ruby not modern enough
2412
2426
  end
@@ -2418,26 +2432,26 @@ class TestLexer < Minitest::Test
2418
2432
 
2419
2433
  def test_fluent_dot
2420
2434
  assert_scanned("x\n.y",
2421
- :tIDENTIFIER, 'x',
2422
- :tDOT, '.',
2423
- :tIDENTIFIER, 'y')
2435
+ :tIDENTIFIER, 'x', [0, 1],
2436
+ :tDOT, '.', [2, 3],
2437
+ :tIDENTIFIER, 'y', [3, 4])
2424
2438
 
2425
2439
  assert_scanned("x\n .y",
2426
- :tIDENTIFIER, 'x',
2427
- :tDOT, '.',
2428
- :tIDENTIFIER, 'y')
2440
+ :tIDENTIFIER, 'x', [0, 1],
2441
+ :tDOT, '.', [4, 5],
2442
+ :tIDENTIFIER, 'y', [5, 6])
2429
2443
 
2430
2444
  assert_scanned("x # comment\n .y",
2431
- :tIDENTIFIER, 'x',
2432
- :tDOT, '.',
2433
- :tIDENTIFIER, 'y')
2445
+ :tIDENTIFIER, 'x', [0, 1],
2446
+ :tDOT, '.', [14, 15],
2447
+ :tIDENTIFIER, 'y', [15, 16])
2434
2448
  end
2435
2449
 
2436
2450
  def test_fluent_and_dot
2437
2451
  assert_scanned("x\n&.y",
2438
- :tIDENTIFIER, 'x',
2439
- :tANDDOT, '&.',
2440
- :tIDENTIFIER, 'y')
2452
+ :tIDENTIFIER, 'x', [0, 1],
2453
+ :tANDDOT, '&.', [2, 4],
2454
+ :tIDENTIFIER, 'y', [4, 5])
2441
2455
  end
2442
2456
 
2443
2457
  #
@@ -2447,23 +2461,23 @@ class TestLexer < Minitest::Test
2447
2461
  def test_whitespace_fname
2448
2462
  @lex.state = :expr_fname
2449
2463
  assert_scanned('class',
2450
- :kCLASS, 'class')
2464
+ :kCLASS, 'class', [0, 5])
2451
2465
 
2452
2466
  @lex.state = :expr_fname
2453
2467
  assert_scanned(' class',
2454
- :kCLASS, 'class')
2468
+ :kCLASS, 'class', [1, 6])
2455
2469
 
2456
2470
  @lex.state = :expr_fname
2457
2471
  assert_scanned("\nclass",
2458
- :kCLASS, 'class')
2472
+ :kCLASS, 'class', [1, 6])
2459
2473
 
2460
2474
  @lex.state = :expr_fname
2461
2475
  assert_scanned("\\\nclass",
2462
- :kCLASS, 'class')
2476
+ :kCLASS, 'class', [2, 7])
2463
2477
 
2464
2478
  @lex.state = :expr_fname
2465
2479
  assert_scanned("#foo\nclass",
2466
- :kCLASS, 'class')
2480
+ :kCLASS, 'class', [5, 10])
2467
2481
  end
2468
2482
 
2469
2483
  def test_whitespace_endfn
@@ -2471,159 +2485,159 @@ class TestLexer < Minitest::Test
2471
2485
 
2472
2486
  @lex.state = :expr_endfn
2473
2487
  assert_scanned('foo:',
2474
- :tLABEL, 'foo')
2488
+ :tLABEL, 'foo', [0, 4])
2475
2489
 
2476
2490
  @lex.state = :expr_endfn
2477
2491
  assert_scanned(' foo:',
2478
- :tLABEL, 'foo')
2492
+ :tLABEL, 'foo', [1, 5])
2479
2493
 
2480
2494
  @lex.state = :expr_endfn
2481
2495
  assert_scanned("\nfoo:",
2482
- :tNL, nil,
2483
- :tIDENTIFIER, 'foo',
2484
- :tCOLON, ':')
2496
+ :tNL, nil, [0, 1],
2497
+ :tIDENTIFIER, 'foo', [1, 4],
2498
+ :tCOLON, ':', [4, 5])
2485
2499
 
2486
2500
  @lex.state = :expr_endfn
2487
2501
  assert_scanned("\nfoo: ",
2488
- :tNL, nil,
2489
- :tIDENTIFIER, 'foo',
2490
- :tCOLON, ':')
2502
+ :tNL, nil, [0, 1],
2503
+ :tIDENTIFIER, 'foo', [1, 4],
2504
+ :tCOLON, ':', [4, 5])
2491
2505
 
2492
2506
  @lex.state = :expr_endfn
2493
2507
  assert_scanned("\\\nfoo:",
2494
- :tLABEL, 'foo')
2508
+ :tLABEL, 'foo', [2, 6])
2495
2509
 
2496
2510
  @lex.state = :expr_endfn
2497
2511
  assert_scanned("#foo\nfoo:",
2498
- :tNL, nil,
2499
- :tIDENTIFIER, 'foo',
2500
- :tCOLON, ':')
2512
+ :tNL, nil, [4, 5],
2513
+ :tIDENTIFIER, 'foo', [5, 8],
2514
+ :tCOLON, ':', [8, 9])
2501
2515
 
2502
2516
  @lex.state = :expr_endfn
2503
2517
  assert_scanned("#foo\nfoo: ",
2504
- :tNL, nil,
2505
- :tIDENTIFIER, 'foo',
2506
- :tCOLON, ':')
2518
+ :tNL, nil, [4, 5],
2519
+ :tIDENTIFIER, 'foo', [5, 8],
2520
+ :tCOLON, ':', [8, 9])
2507
2521
  end
2508
2522
 
2509
2523
  def test_whitespace_dot
2510
2524
  @lex.state = :expr_dot
2511
2525
  assert_scanned('class',
2512
- :tIDENTIFIER, 'class')
2526
+ :tIDENTIFIER, 'class', [0, 5])
2513
2527
 
2514
2528
  @lex.state = :expr_dot
2515
2529
  assert_scanned(' class',
2516
- :tIDENTIFIER, 'class')
2530
+ :tIDENTIFIER, 'class', [1, 6])
2517
2531
 
2518
2532
  @lex.state = :expr_dot
2519
2533
  assert_scanned("\nclass",
2520
- :tIDENTIFIER, 'class')
2534
+ :tIDENTIFIER, 'class', [1, 6])
2521
2535
 
2522
2536
  @lex.state = :expr_dot
2523
2537
  assert_scanned("\\\nclass",
2524
- :tIDENTIFIER, 'class')
2538
+ :tIDENTIFIER, 'class', [2, 7])
2525
2539
 
2526
2540
  @lex.state = :expr_dot
2527
2541
  assert_scanned("#foo\nclass",
2528
- :tIDENTIFIER, 'class')
2542
+ :tIDENTIFIER, 'class', [5, 10])
2529
2543
  end
2530
2544
 
2531
2545
  def test_whitespace_arg
2532
2546
  @lex.state = :expr_arg
2533
2547
  assert_scanned('+',
2534
- :tPLUS, '+')
2548
+ :tPLUS, '+', [0, 1])
2535
2549
 
2536
2550
  @lex.state = :expr_arg
2537
2551
  assert_scanned(' +',
2538
- :tUPLUS, '+')
2552
+ :tUPLUS, '+', [1, 2])
2539
2553
 
2540
2554
  @lex.state = :expr_arg
2541
2555
  assert_scanned("\n+",
2542
- :tNL, nil,
2543
- :tUPLUS, '+')
2556
+ :tNL, nil, [0, 1],
2557
+ :tUPLUS, '+', [1, 2])
2544
2558
 
2545
2559
  @lex.state = :expr_arg
2546
2560
  assert_scanned("\\\n+",
2547
- :tUPLUS, '+')
2561
+ :tUPLUS, '+', [2, 3])
2548
2562
 
2549
2563
  @lex.state = :expr_arg
2550
2564
  assert_scanned("\\\n +",
2551
- :tUPLUS, '+')
2565
+ :tUPLUS, '+', [3, 4])
2552
2566
 
2553
2567
  @lex.state = :expr_arg
2554
2568
  assert_scanned("#foo\n+",
2555
- :tNL, nil,
2556
- :tUPLUS, '+')
2569
+ :tNL, nil, [4, 5],
2570
+ :tUPLUS, '+', [5, 6])
2557
2571
  end
2558
2572
 
2559
2573
  def test_whitespace_endarg
2560
2574
  @lex.state = :expr_endarg
2561
2575
  assert_scanned('{',
2562
- :tLBRACE_ARG, '{')
2576
+ :tLBRACE_ARG, '{', [0, 1])
2563
2577
 
2564
2578
  @lex.state = :expr_endarg
2565
2579
  assert_scanned(' {',
2566
- :tLBRACE_ARG, '{')
2580
+ :tLBRACE_ARG, '{', [1, 2])
2567
2581
 
2568
2582
  @lex.state = :expr_endarg
2569
2583
  assert_scanned("\n{",
2570
- :tNL, nil,
2571
- :tLBRACE, '{')
2584
+ :tNL, nil, [0, 1],
2585
+ :tLBRACE, '{', [1, 2])
2572
2586
 
2573
2587
  @lex.state = :expr_endarg
2574
2588
  assert_scanned("\\\n{",
2575
- :tLBRACE_ARG, '{')
2589
+ :tLBRACE_ARG, '{', [2, 3])
2576
2590
 
2577
2591
  @lex.state = :expr_endarg
2578
2592
  assert_scanned("#foo\n{",
2579
- :tNL, nil,
2580
- :tLBRACE, '{')
2593
+ :tNL, nil, [4, 5],
2594
+ :tLBRACE, '{', [5, 6])
2581
2595
  end
2582
2596
 
2583
2597
  def test_whitespace_mid
2584
2598
  @lex.state = :expr_mid
2585
2599
  assert_scanned('+',
2586
- :tUPLUS, '+')
2600
+ :tUPLUS, '+', [0, 1])
2587
2601
 
2588
2602
  @lex.state = :expr_mid
2589
2603
  assert_scanned(' +',
2590
- :tUPLUS, '+')
2604
+ :tUPLUS, '+', [1, 2])
2591
2605
 
2592
2606
  @lex.state = :expr_mid
2593
2607
  assert_scanned("\n+",
2594
- :tNL, nil,
2595
- :tUPLUS, '+')
2608
+ :tNL, nil, [0, 1],
2609
+ :tUPLUS, '+', [1, 2])
2596
2610
 
2597
2611
  @lex.state = :expr_mid
2598
2612
  assert_scanned("\\\n+",
2599
- :tUPLUS, '+')
2613
+ :tUPLUS, '+', [2, 3])
2600
2614
 
2601
2615
  @lex.state = :expr_mid
2602
2616
  assert_scanned("#foo\n+",
2603
- :tNL, nil,
2604
- :tUPLUS, '+')
2617
+ :tNL, nil, [4, 5],
2618
+ :tUPLUS, '+', [5, 6])
2605
2619
  end
2606
2620
 
2607
2621
  def test_whitespace_beg
2608
2622
  @lex.state = :expr_beg
2609
2623
  assert_scanned('+',
2610
- :tUPLUS, '+')
2624
+ :tUPLUS, '+', [0, 1])
2611
2625
 
2612
2626
  @lex.state = :expr_beg
2613
2627
  assert_scanned(' +',
2614
- :tUPLUS, '+')
2628
+ :tUPLUS, '+', [1, 2])
2615
2629
 
2616
2630
  @lex.state = :expr_beg
2617
2631
  assert_scanned("\n+",
2618
- :tUPLUS, '+')
2632
+ :tUPLUS, '+', [1, 2])
2619
2633
 
2620
2634
  @lex.state = :expr_beg
2621
2635
  assert_scanned("\\\n+",
2622
- :tUPLUS, '+')
2636
+ :tUPLUS, '+', [2, 3])
2623
2637
 
2624
2638
  @lex.state = :expr_beg
2625
2639
  assert_scanned("#foo\n+",
2626
- :tUPLUS, '+')
2640
+ :tUPLUS, '+', [5, 6])
2627
2641
  end
2628
2642
 
2629
2643
  def test_whitespace_value
@@ -2631,71 +2645,91 @@ class TestLexer < Minitest::Test
2631
2645
 
2632
2646
  @lex.state = :expr_value
2633
2647
  assert_scanned('a:b',
2634
- :tIDENTIFIER, 'a',
2635
- :tSYMBOL, 'b')
2648
+ :tIDENTIFIER, 'a', [0, 1],
2649
+ :tSYMBOL, 'b', [1, 3])
2636
2650
 
2637
2651
  @lex.state = :expr_value
2638
2652
  assert_scanned(' a:b',
2639
- :tIDENTIFIER, 'a',
2640
- :tSYMBOL, 'b')
2653
+ :tIDENTIFIER, 'a', [1, 2],
2654
+ :tSYMBOL, 'b', [2, 4])
2641
2655
 
2642
2656
  @lex.state = :expr_value
2643
2657
  assert_scanned("\na:b",
2644
- :tIDENTIFIER, 'a',
2645
- :tSYMBOL, 'b')
2658
+ :tIDENTIFIER, 'a', [1, 2],
2659
+ :tSYMBOL, 'b', [2, 4])
2646
2660
 
2647
2661
  @lex.state = :expr_value
2648
2662
  assert_scanned("\\\na:b",
2649
- :tIDENTIFIER, 'a',
2650
- :tSYMBOL, 'b')
2663
+ :tIDENTIFIER, 'a', [2, 3],
2664
+ :tSYMBOL, 'b', [3, 5])
2651
2665
 
2652
2666
  @lex.state = :expr_value
2653
2667
  assert_scanned("#foo\na:b",
2654
- :tIDENTIFIER, 'a',
2655
- :tSYMBOL, 'b')
2668
+ :tIDENTIFIER, 'a', [5, 6],
2669
+ :tSYMBOL, 'b', [6, 8])
2656
2670
  end
2657
2671
 
2658
2672
  def test_whitespace_end
2659
2673
  @lex.state = :expr_end
2660
2674
  assert_scanned('+ 1',
2661
- :tPLUS, '+',
2662
- :tINTEGER, 1)
2675
+ :tPLUS, '+', [0, 1],
2676
+ :tINTEGER, 1, [2, 3])
2663
2677
 
2664
2678
  @lex.state = :expr_end
2665
2679
  assert_scanned(' + 1',
2666
- :tPLUS, '+',
2667
- :tINTEGER, 1)
2680
+ :tPLUS, '+', [1, 2],
2681
+ :tINTEGER, 1, [3, 4])
2668
2682
 
2669
2683
  @lex.state = :expr_end
2670
2684
  assert_scanned("\n+ 1",
2671
- :tNL, nil,
2672
- :tUPLUS, '+',
2673
- :tINTEGER, 1)
2685
+ :tNL, nil, [0, 1],
2686
+ :tUPLUS, '+', [1, 2],
2687
+ :tINTEGER, 1, [3, 4])
2674
2688
 
2675
2689
  @lex.state = :expr_end
2676
2690
  assert_scanned("\\\n+ 1",
2677
- :tPLUS, '+',
2678
- :tINTEGER, 1)
2691
+ :tPLUS, '+', [2, 3],
2692
+ :tINTEGER, 1, [4, 5])
2679
2693
 
2680
2694
  @lex.state = :expr_end
2681
2695
  assert_scanned("#foo\n+ 1",
2682
- :tNL, nil,
2683
- :tUPLUS, '+',
2684
- :tINTEGER, 1)
2696
+ :tNL, nil, [4, 5],
2697
+ :tUPLUS, '+', [5, 6],
2698
+ :tINTEGER, 1, [7, 8])
2685
2699
  end
2686
2700
 
2687
2701
  def test_whitespace_cr
2688
2702
  setup_lexer(20)
2689
2703
  assert_scanned("<<E\nfoo\nE\rO",
2690
- :tSTRING_BEG, '<<"',
2691
- :tSTRING_CONTENT, "foo\n",
2692
- :tSTRING_END, 'E',
2693
- :tNL, nil)
2704
+ :tSTRING_BEG, '<<"', [0, 3],
2705
+ :tSTRING_CONTENT, "foo\n", [4, 8],
2706
+ :tSTRING_END, 'E', [8, 11],
2707
+ :tNL, nil, [3, 4])
2694
2708
 
2695
2709
  setup_lexer(21)
2696
2710
  refute_scanned("<<E\nfoo\nE\rO",
2697
- :tSTRING_BEG, '<<"',
2698
- :tSTRING_CONTENT, "foo\n")
2711
+ :tSTRING_BEG, '<<"', [0, 3],
2712
+ :tSTRING_CONTENT, "foo\n", [4, 8])
2713
+ end
2714
+
2715
+ #
2716
+ # Handling of encoding-related issues.
2717
+ #
2718
+
2719
+ if defined?(Encoding)
2720
+ def test_transcoded_source_is_converted_back_to_original_encoding
2721
+ setup_lexer(19)
2722
+ @lex.force_utf32 = true
2723
+ @lex.tokens = []
2724
+ assert_scanned(utf('"a" + "b"'),
2725
+ :tSTRING, "a", [0, 3],
2726
+ :tPLUS, "+", [4, 5],
2727
+ :tSTRING, "b", [6, 9])
2728
+
2729
+ @lex.tokens.each do |_type, (str, _range)|
2730
+ assert_equal Encoding::UTF_8, str.encoding
2731
+ end
2732
+ end
2699
2733
  end
2700
2734
 
2701
2735
  #
@@ -2707,14 +2741,14 @@ class TestLexer < Minitest::Test
2707
2741
 
2708
2742
  def test_bug_sclass_joined
2709
2743
  assert_scanned("class<<self",
2710
- :kCLASS, "class",
2711
- :tLSHFT, "<<",
2712
- :kSELF, "self")
2744
+ :kCLASS, "class", [0, 5],
2745
+ :tLSHFT, "<<", [5, 7],
2746
+ :kSELF, "self", [7, 11])
2713
2747
  end
2714
2748
 
2715
2749
  def test_bug_const_expr_end
2716
2750
  assert_scanned("Option",
2717
- :tCONSTANT, 'Option')
2751
+ :tCONSTANT, 'Option', [0, 6])
2718
2752
 
2719
2753
  assert_equal :expr_cmdarg, @lex.state
2720
2754
  end
@@ -2722,141 +2756,141 @@ class TestLexer < Minitest::Test
2722
2756
  def test_bug_expr_beg_div
2723
2757
  @lex.state = :expr_beg
2724
2758
  assert_scanned("/=/",
2725
- :tREGEXP_BEG, "/",
2726
- :tSTRING_CONTENT, "=",
2727
- :tSTRING_END, "/",
2728
- :tREGEXP_OPT, "")
2759
+ :tREGEXP_BEG, "/", [0, 1],
2760
+ :tSTRING_CONTENT, "=", [1, 2],
2761
+ :tSTRING_END, "/", [2, 3],
2762
+ :tREGEXP_OPT, "", [3, 3])
2729
2763
 
2730
2764
  @lex.state = :expr_beg
2731
2765
  assert_scanned("/ = /",
2732
- :tREGEXP_BEG, "/",
2733
- :tSTRING_CONTENT, " = ",
2734
- :tSTRING_END, "/",
2735
- :tREGEXP_OPT, "")
2766
+ :tREGEXP_BEG, "/", [0, 1],
2767
+ :tSTRING_CONTENT, " = ", [1, 4],
2768
+ :tSTRING_END, "/", [4, 5],
2769
+ :tREGEXP_OPT, "", [5, 5])
2736
2770
  end
2737
2771
 
2738
2772
  def test_bug_expr_beg_percent
2739
2773
  @lex.state = :expr_beg
2740
2774
  assert_scanned("%=foo=",
2741
- :tSTRING_BEG, "%=",
2742
- :tSTRING_CONTENT, 'foo',
2743
- :tSTRING_END, "=")
2775
+ :tSTRING_BEG, "%=", [0, 2],
2776
+ :tSTRING_CONTENT, 'foo', [2, 5],
2777
+ :tSTRING_END, "=", [5, 6])
2744
2778
 
2745
2779
  @lex.state = :expr_beg
2746
2780
  assert_scanned("% = ",
2747
- :tSTRING_BEG, "% ",
2748
- :tSTRING_CONTENT, '=',
2749
- :tSTRING_END, ' ')
2781
+ :tSTRING_BEG, "% ", [0, 2],
2782
+ :tSTRING_CONTENT, '=', [2, 3],
2783
+ :tSTRING_END, ' ', [3, 4])
2750
2784
  end
2751
2785
 
2752
2786
  def test_bug_expr_beg_document
2753
2787
  @lex.state = :expr_beg
2754
2788
  assert_scanned(" \n=begin\n=end\nend",
2755
- :kEND, "end")
2789
+ :kEND, "end", [14, 17])
2756
2790
 
2757
2791
  end
2758
2792
 
2759
2793
  def test_bug_expr_beg_number
2760
2794
  @lex.state = :expr_beg
2761
2795
  assert_scanned("86400_000_000",
2762
- :tINTEGER, 86400_000_000)
2796
+ :tINTEGER, 86400_000_000, [0, 13])
2763
2797
  end
2764
2798
 
2765
2799
  def test_bug_expr_beg_backspace_nl
2766
2800
  @lex.state = :expr_beg
2767
2801
  assert_scanned("\n/foo/",
2768
- :tREGEXP_BEG, "/",
2769
- :tSTRING_CONTENT, "foo",
2770
- :tSTRING_END, "/",
2771
- :tREGEXP_OPT, "")
2802
+ :tREGEXP_BEG, "/", [1, 2],
2803
+ :tSTRING_CONTENT, "foo", [2, 5],
2804
+ :tSTRING_END, "/", [5, 6],
2805
+ :tREGEXP_OPT, "", [6, 6])
2772
2806
  end
2773
2807
 
2774
2808
  def test_bug_expr_beg_heredoc
2775
2809
  assert_scanned("<<EOL % [\nfoo\nEOL\n]",
2776
- :tSTRING_BEG, '<<"',
2777
- :tSTRING_CONTENT, "foo\n",
2778
- :tSTRING_END, 'EOL',
2779
- :tPERCENT, '%',
2780
- :tLBRACK, '[',
2781
- :tRBRACK, ']')
2810
+ :tSTRING_BEG, '<<"', [0, 5],
2811
+ :tSTRING_CONTENT, "foo\n", [10, 14],
2812
+ :tSTRING_END, 'EOL', [14, 17],
2813
+ :tPERCENT, '%', [6, 7],
2814
+ :tLBRACK, '[', [8, 9],
2815
+ :tRBRACK, ']', [18, 19])
2782
2816
  end
2783
2817
 
2784
2818
  def test_bug_expr_beg_fid
2785
2819
  assert_scanned("Rainbows!",
2786
- :tFID, 'Rainbows!')
2820
+ :tFID, 'Rainbows!', [0, 9])
2787
2821
  end
2788
2822
 
2789
2823
  def test_bug_expr_beg_rescue_assoc
2790
2824
  assert_scanned("rescue=>",
2791
- :kRESCUE, 'rescue',
2792
- :tASSOC, '=>')
2825
+ :kRESCUE, 'rescue', [0, 6],
2826
+ :tASSOC, '=>', [6, 8])
2793
2827
  end
2794
2828
 
2795
2829
  def test_bug_expr_arg_percent
2796
2830
  @lex.state = :expr_arg
2797
2831
  assert_scanned("%[",
2798
- :tPERCENT, "%",
2799
- :tLBRACK, "[")
2832
+ :tPERCENT, "%", [0, 1],
2833
+ :tLBRACK, "[", [1, 2])
2800
2834
 
2801
2835
  @lex.state = :expr_arg
2802
2836
  assert_scanned("%=1",
2803
- :tOP_ASGN, "%",
2804
- :tINTEGER, 1)
2837
+ :tOP_ASGN, "%", [0, 2],
2838
+ :tINTEGER, 1, [2, 3])
2805
2839
 
2806
2840
  @lex.state = :expr_arg
2807
2841
  assert_scanned(" %[1]",
2808
- :tSTRING_BEG, "%[",
2809
- :tSTRING_CONTENT, '1',
2810
- :tSTRING_END, ']')
2842
+ :tSTRING_BEG, "%[", [1, 3],
2843
+ :tSTRING_CONTENT, '1', [3, 4],
2844
+ :tSTRING_END, ']', [4, 5])
2811
2845
 
2812
2846
  @lex.state = :expr_arg
2813
2847
  assert_scanned(" %=1=",
2814
- :tOP_ASGN, "%",
2815
- :tINTEGER, 1,
2816
- :tEQL, "=")
2848
+ :tOP_ASGN, "%", [1, 3],
2849
+ :tINTEGER, 1, [3, 4],
2850
+ :tEQL, "=", [4, 5])
2817
2851
 
2818
2852
  @lex.state = :expr_arg
2819
2853
  assert_scanned(" %\n",
2820
- :tPERCENT, '%')
2854
+ :tPERCENT, '%', [1, 2])
2821
2855
  end
2822
2856
 
2823
2857
  def test_bug_expr_arg_lt_lt
2824
2858
  @lex.state = :expr_arg
2825
2859
  assert_scanned("<<EOS\nEOS",
2826
- :tLSHFT, "<<",
2827
- :tCONSTANT, "EOS",
2828
- :tNL, nil,
2829
- :tCONSTANT, "EOS")
2860
+ :tLSHFT, "<<", [0, 2],
2861
+ :tCONSTANT, "EOS", [2, 5],
2862
+ :tNL, nil, [5, 6],
2863
+ :tCONSTANT, "EOS", [6, 9])
2830
2864
 
2831
2865
  @lex.state = :expr_arg
2832
2866
  assert_scanned(" <<EOS\nEOS",
2833
- :tSTRING_BEG, "<<\"",
2834
- :tSTRING_END, "EOS",
2835
- :tNL, nil)
2867
+ :tSTRING_BEG, "<<\"", [1, 6],
2868
+ :tSTRING_END, "EOS", [7, 10],
2869
+ :tNL, nil, [6, 7])
2836
2870
  end
2837
2871
 
2838
2872
  def test_bug_expr_arg_slash
2839
2873
  @lex.state = :expr_arg
2840
2874
  assert_scanned("/1",
2841
- :tDIVIDE, "/",
2842
- :tINTEGER, 1)
2875
+ :tDIVIDE, "/", [0, 1],
2876
+ :tINTEGER, 1, [1, 2])
2843
2877
 
2844
2878
  @lex.state = :expr_arg
2845
2879
  assert_scanned("/ 1",
2846
- :tDIVIDE, "/",
2847
- :tINTEGER, 1)
2880
+ :tDIVIDE, "/", [0, 1],
2881
+ :tINTEGER, 1, [2, 3])
2848
2882
 
2849
2883
  @lex.state = :expr_arg
2850
2884
  assert_scanned(" /1/",
2851
- :tREGEXP_BEG, "/",
2852
- :tSTRING_CONTENT, "1",
2853
- :tSTRING_END, "/",
2854
- :tREGEXP_OPT, "")
2885
+ :tREGEXP_BEG, "/", [1, 2],
2886
+ :tSTRING_CONTENT, "1", [2, 3],
2887
+ :tSTRING_END, "/", [3, 4],
2888
+ :tREGEXP_OPT, "", [4, 4])
2855
2889
 
2856
2890
  @lex.state = :expr_arg
2857
2891
  assert_scanned(" / 1",
2858
- :tDIVIDE, "/",
2859
- :tINTEGER, 1)
2892
+ :tDIVIDE, "/", [1, 2],
2893
+ :tINTEGER, 1, [3, 4])
2860
2894
  end
2861
2895
 
2862
2896
  def test_bug_expr_arg_label
@@ -2864,241 +2898,241 @@ class TestLexer < Minitest::Test
2864
2898
 
2865
2899
  @lex.state = :expr_arg
2866
2900
  assert_scanned(" unless:",
2867
- :tLABEL, 'unless')
2901
+ :tLABEL, 'unless', [1, 8])
2868
2902
 
2869
2903
  @lex.state = :expr_arg
2870
2904
  assert_scanned(" unless: ",
2871
- :tLABEL, 'unless')
2905
+ :tLABEL, 'unless', [1, 8])
2872
2906
  end
2873
2907
 
2874
2908
  def test_bug_heredoc_continuation
2875
2909
  @lex.state = :expr_arg
2876
2910
  assert_scanned(" <<EOS\nEOS\nend",
2877
- :tSTRING_BEG, "<<\"",
2878
- :tSTRING_END, "EOS",
2879
- :tNL, nil,
2880
- :kEND, "end")
2911
+ :tSTRING_BEG, "<<\"", [1, 6],
2912
+ :tSTRING_END, "EOS", [7, 10],
2913
+ :tNL, nil, [6, 7],
2914
+ :kEND, "end", [11, 14])
2881
2915
  end
2882
2916
 
2883
2917
  def test_bug_heredoc_cr_lf
2884
2918
  assert_scanned("<<FIN\r\nfoo\r\nFIN\r\n",
2885
- :tSTRING_BEG, "<<\"",
2886
- :tSTRING_CONTENT, "foo\n",
2887
- :tSTRING_END, "FIN",
2888
- :tNL, nil)
2919
+ :tSTRING_BEG, "<<\"", [0, 5],
2920
+ :tSTRING_CONTENT, "foo\n", [6, 10],
2921
+ :tSTRING_END, "FIN", [10, 13],
2922
+ :tNL, nil, [5, 6])
2889
2923
  end
2890
2924
 
2891
2925
  def test_bug_eh_symbol_no_newline
2892
2926
  assert_scanned("?\"\nfoo",
2893
- :tINTEGER, 34,
2894
- :tNL, nil,
2895
- :tIDENTIFIER, "foo")
2927
+ :tINTEGER, 34, [0, 2],
2928
+ :tNL, nil, [2, 3],
2929
+ :tIDENTIFIER, "foo", [3, 6])
2896
2930
  end
2897
2931
 
2898
2932
  def test_bug_expr_arg_newline
2899
2933
  @lex.state = :expr_arg
2900
2934
  assert_scanned("\nfoo",
2901
- :tNL, nil,
2902
- :tIDENTIFIER, "foo")
2935
+ :tNL, nil, [0, 1],
2936
+ :tIDENTIFIER, "foo", [1, 4])
2903
2937
 
2904
2938
  @lex.state = :expr_arg
2905
2939
  assert_scanned(" \nfoo",
2906
- :tNL, nil,
2907
- :tIDENTIFIER, "foo")
2940
+ :tNL, nil, [1, 2],
2941
+ :tIDENTIFIER, "foo", [2, 5])
2908
2942
 
2909
2943
  @lex.state = :expr_arg
2910
2944
  assert_scanned("#foo\nfoo",
2911
- :tNL, nil,
2912
- :tIDENTIFIER, "foo")
2945
+ :tNL, nil, [4, 5],
2946
+ :tIDENTIFIER, "foo", [5, 8])
2913
2947
  end
2914
2948
 
2915
2949
  def test_bug_expr_arg_comment_newline
2916
2950
  @lex.state = :expr_arg
2917
2951
  assert_scanned(" #\nfoo",
2918
- :tNL, nil,
2919
- :tIDENTIFIER, 'foo')
2952
+ :tNL, nil, [2, 3],
2953
+ :tIDENTIFIER, 'foo', [3, 6])
2920
2954
  end
2921
2955
 
2922
2956
  def test_bug_expr_arg_eh_crlf
2923
2957
  @lex.state = :expr_arg
2924
2958
  assert_scanned(" ?\r\n",
2925
- :tEH, '?')
2959
+ :tEH, '?', [1, 2])
2926
2960
  end
2927
2961
 
2928
2962
  def test_bug_heredoc_backspace_nl
2929
2963
  assert_scanned(" <<'XXX'\nf \\\nXXX\n",
2930
- :tSTRING_BEG, "<<'",
2931
- :tSTRING_CONTENT, "f \\\n",
2932
- :tSTRING_END, "XXX",
2933
- :tNL, nil)
2964
+ :tSTRING_BEG, "<<'", [1, 8],
2965
+ :tSTRING_CONTENT, "f \\\n", [9, 13],
2966
+ :tSTRING_END, "XXX", [13, 16],
2967
+ :tNL, nil, [8, 9])
2934
2968
  end
2935
2969
 
2936
2970
  def test_bug_heredoc_lshft
2937
2971
  assert_scanned("<<RULES << CLEANINGS\nRULES",
2938
- :tSTRING_BEG, '<<"',
2939
- :tSTRING_END, 'RULES',
2940
- :tLSHFT, '<<',
2941
- :tCONSTANT, 'CLEANINGS')
2972
+ :tSTRING_BEG, '<<"', [0, 7],
2973
+ :tSTRING_END, 'RULES', [21, 26],
2974
+ :tLSHFT, '<<', [8, 10],
2975
+ :tCONSTANT, 'CLEANINGS', [11, 20])
2942
2976
  end
2943
2977
 
2944
2978
  def test_bug_sclass_comment_lshft_label
2945
2979
  assert_scanned("class # foo\n<< a:b;end",
2946
- :kCLASS, 'class',
2947
- :tLSHFT, '<<',
2948
- :tIDENTIFIER, 'a',
2949
- :tSYMBOL, 'b',
2950
- :tSEMI, ';',
2951
- :kEND, 'end')
2980
+ :kCLASS, 'class', [0, 5],
2981
+ :tLSHFT, '<<', [12, 14],
2982
+ :tIDENTIFIER, 'a', [15, 16],
2983
+ :tSYMBOL, 'b', [16, 18],
2984
+ :tSEMI, ';', [18, 19],
2985
+ :kEND, 'end', [19, 22])
2952
2986
  end
2953
2987
 
2954
2988
  def test_bug_expr_dot_comment
2955
2989
  assert_scanned("foo. #bar\nbaz",
2956
- :tIDENTIFIER, 'foo',
2957
- :tDOT, '.',
2958
- :tIDENTIFIER, 'baz')
2990
+ :tIDENTIFIER, 'foo', [0, 3],
2991
+ :tDOT, '.', [3, 4],
2992
+ :tIDENTIFIER, 'baz', [10, 13])
2959
2993
  end
2960
2994
 
2961
2995
  def test_bug_expr_dot_fid
2962
2996
  assert_scanned("foo.S?",
2963
- :tIDENTIFIER, 'foo',
2964
- :tDOT, '.',
2965
- :tFID, 'S?')
2997
+ :tIDENTIFIER, 'foo', [0, 3],
2998
+ :tDOT, '.', [3, 4],
2999
+ :tFID, 'S?', [4, 6])
2966
3000
  end
2967
3001
 
2968
3002
  def test_bug_expr_dot_id_eq
2969
3003
  assert_scanned("foo.x= 1",
2970
- :tIDENTIFIER, 'foo',
2971
- :tDOT, '.',
2972
- :tIDENTIFIER, 'x',
2973
- :tEQL, '=',
2974
- :tINTEGER, 1)
3004
+ :tIDENTIFIER, 'foo', [0, 3],
3005
+ :tDOT, '.', [3, 4],
3006
+ :tIDENTIFIER, 'x', [4, 5],
3007
+ :tEQL, '=', [5, 6],
3008
+ :tINTEGER, 1, [7, 8])
2975
3009
  end
2976
3010
 
2977
3011
  def test_bug_expr_dot_fid_mod
2978
3012
  assert_scanned("foo.x!if 1",
2979
- :tIDENTIFIER, 'foo',
2980
- :tDOT, '.',
2981
- :tFID, 'x!',
2982
- :kIF_MOD, 'if',
2983
- :tINTEGER, 1)
3013
+ :tIDENTIFIER, 'foo', [0, 3],
3014
+ :tDOT, '.', [3, 4],
3015
+ :tFID, 'x!', [4, 6],
3016
+ :kIF_MOD, 'if', [6, 8],
3017
+ :tINTEGER, 1, [9, 10])
2984
3018
  end
2985
3019
 
2986
3020
  def test_bug_expr_mid_comment
2987
3021
  assert_scanned("rescue #bar\nprint",
2988
- :kRESCUE, 'rescue',
2989
- :tNL, nil,
2990
- :tIDENTIFIER, 'print')
3022
+ :kRESCUE, 'rescue', [0, 6],
3023
+ :tNL, nil, [11, 12],
3024
+ :tIDENTIFIER, 'print', [12, 17])
2991
3025
  end
2992
3026
 
2993
3027
  def test_bug_expr_mid_bareword
2994
3028
  assert_scanned("begin; rescue rescue1",
2995
- :kBEGIN, 'begin',
2996
- :tSEMI, ';',
2997
- :kRESCUE, 'rescue',
2998
- :tIDENTIFIER, 'rescue1')
3029
+ :kBEGIN, 'begin', [0, 5],
3030
+ :tSEMI, ';', [5, 6],
3031
+ :kRESCUE, 'rescue', [7, 13],
3032
+ :tIDENTIFIER, 'rescue1', [14, 21])
2999
3033
  end
3000
3034
 
3001
3035
  def test_bug_expr_value_document
3002
3036
  assert_scanned("1;\n=begin\n=end",
3003
- :tINTEGER, 1,
3004
- :tSEMI, ';')
3037
+ :tINTEGER, 1, [0, 1],
3038
+ :tSEMI, ';', [1, 2])
3005
3039
  end
3006
3040
 
3007
3041
  def test_bug_expr_end_colon
3008
3042
  assert_scanned("'foo':'bar'",
3009
- :tSTRING, 'foo',
3010
- :tCOLON, ':',
3011
- :tSTRING, 'bar')
3043
+ :tSTRING, 'foo', [0, 5],
3044
+ :tCOLON, ':', [5, 6],
3045
+ :tSTRING, 'bar', [6, 11])
3012
3046
  end
3013
3047
 
3014
3048
  def test_bug_expr_value_rescue_colon2
3015
3049
  @lex.state = :expr_value
3016
3050
  assert_scanned("rescue::Exception",
3017
- :kRESCUE, 'rescue',
3018
- :tCOLON3, '::',
3019
- :tCONSTANT, 'Exception')
3051
+ :kRESCUE, 'rescue', [0, 6],
3052
+ :tCOLON3, '::', [6, 8],
3053
+ :tCONSTANT, 'Exception', [8, 17])
3020
3054
  end
3021
3055
 
3022
3056
  def test_bug_expr_endarg_braces
3023
3057
  assert_scanned("let [] {",
3024
- :tIDENTIFIER, 'let',
3025
- :tLBRACK, '[',
3026
- :tRBRACK, ']',
3027
- :tLBRACE_ARG, '{')
3058
+ :tIDENTIFIER, 'let', [0, 3],
3059
+ :tLBRACK, '[', [4, 5],
3060
+ :tRBRACK, ']', [5, 6],
3061
+ :tLBRACE_ARG, '{', [7, 8])
3028
3062
  end
3029
3063
 
3030
3064
  def test_bug_line_begin_label
3031
3065
  setup_lexer(19)
3032
3066
  assert_scanned("foo:bar",
3033
- :tIDENTIFIER, 'foo',
3034
- :tSYMBOL, 'bar')
3067
+ :tIDENTIFIER, 'foo', [0, 3],
3068
+ :tSYMBOL, 'bar', [3, 7])
3035
3069
  end
3036
3070
 
3037
3071
  def test_bug_interp_expr_value
3038
3072
  assert_scanned('"#{f:a}"',
3039
- :tSTRING_BEG, '"',
3040
- :tSTRING_DBEG, '#{',
3041
- :tIDENTIFIER, 'f',
3042
- :tSYMBOL, 'a',
3043
- :tRCURLY, '}',
3044
- :tSTRING_END, '"')
3073
+ :tSTRING_BEG, '"', [0, 1],
3074
+ :tSTRING_DBEG, '#{', [1, 3],
3075
+ :tIDENTIFIER, 'f', [3, 4],
3076
+ :tSYMBOL, 'a', [4, 6],
3077
+ :tRCURLY, '}', [6, 7],
3078
+ :tSTRING_END, '"', [7, 8])
3045
3079
  end
3046
3080
 
3047
3081
  def test_bug_const_e
3048
3082
  assert_scanned('E10',
3049
- :tCONSTANT, 'E10')
3083
+ :tCONSTANT, 'E10', [0, 3])
3050
3084
  assert_scanned('E4U',
3051
- :tCONSTANT, 'E4U')
3085
+ :tCONSTANT, 'E4U', [0, 3])
3052
3086
  end
3053
3087
 
3054
3088
  def test_bug_symbol_newline
3055
3089
  assert_scanned(":foo\n",
3056
- :tSYMBOL, 'foo',
3057
- :tNL, nil)
3090
+ :tSYMBOL, 'foo', [0, 4],
3091
+ :tNL, nil, [4, 5])
3058
3092
 
3059
3093
  assert_scanned(":foo=\n",
3060
- :tSYMBOL, 'foo=',
3061
- :tNL, nil)
3094
+ :tSYMBOL, 'foo=', [0, 5],
3095
+ :tNL, nil, [5, 6])
3062
3096
  end
3063
3097
 
3064
3098
  def test_bug_interleaved_heredoc
3065
3099
  assert_scanned(%Q{<<w; "\nfoo\nw\n"},
3066
- :tSTRING_BEG, '<<"',
3067
- :tSTRING_CONTENT, "foo\n",
3068
- :tSTRING_END, 'w',
3069
- :tSEMI, ';',
3070
- :tSTRING_BEG, '"',
3071
- :tSTRING_CONTENT, "\n",
3072
- :tSTRING_END, '"')
3100
+ :tSTRING_BEG, '<<"', [0, 3],
3101
+ :tSTRING_CONTENT, "foo\n", [7, 11],
3102
+ :tSTRING_END, 'w', [11, 12],
3103
+ :tSEMI, ';', [3, 4],
3104
+ :tSTRING_BEG, '"', [5, 6],
3105
+ :tSTRING_CONTENT, "\n", [6, 7],
3106
+ :tSTRING_END, '"', [13, 14])
3073
3107
 
3074
3108
  @lex.state = :expr_beg
3075
3109
  assert_scanned(%Q{<<w; %w[\nfoo\nw\n1]},
3076
- :tSTRING_BEG, '<<"',
3077
- :tSTRING_CONTENT, "foo\n",
3078
- :tSTRING_END, 'w',
3079
- :tSEMI, ';',
3080
- :tQWORDS_BEG, '%w[',
3081
- :tSTRING_CONTENT, "1",
3082
- :tSPACE, nil,
3083
- :tSTRING_END, ']')
3084
-
3085
- @lex.state = :expr_beg
3110
+ :tSTRING_BEG, '<<"', [0, 3],
3111
+ :tSTRING_CONTENT, "foo\n", [9, 13],
3112
+ :tSTRING_END, 'w', [13, 14],
3113
+ :tSEMI, ';', [3, 4],
3114
+ :tQWORDS_BEG, '%w[', [5, 8],
3115
+ :tSTRING_CONTENT, "1", [15, 16],
3116
+ :tSPACE, nil, [16, 16],
3117
+ :tSTRING_END, ']', [16, 17])
3118
+
3119
+ @lex.state = :expr_beg
3086
3120
  assert_scanned(%Q{<<w; "\#{\nfoo\nw\n}"},
3087
- :tSTRING_BEG, '<<"',
3088
- :tSTRING_CONTENT, "foo\n",
3089
- :tSTRING_END, 'w',
3090
- :tSEMI, ';',
3091
- :tSTRING_BEG, '"',
3092
- :tSTRING_DBEG, '#{',
3093
- :tRCURLY, '}',
3094
- :tSTRING_END, '"')
3121
+ :tSTRING_BEG, '<<"', [0, 3],
3122
+ :tSTRING_CONTENT, "foo\n", [9, 13],
3123
+ :tSTRING_END, 'w', [13, 14],
3124
+ :tSEMI, ';', [3, 4],
3125
+ :tSTRING_BEG, '"', [5, 6],
3126
+ :tSTRING_DBEG, '#{', [6, 8],
3127
+ :tRCURLY, '}', [15, 16],
3128
+ :tSTRING_END, '"', [16, 17])
3095
3129
  end
3096
3130
 
3097
3131
  def test_bug_fid_char
3098
3132
  setup_lexer(19)
3099
- assert_scanned(%Q{eof??a},
3100
- :tFID, 'eof?',
3101
- :tCHARACTER, 'a')
3133
+ assert_scanned('eof??a',
3134
+ :tFID, 'eof?', [0, 4],
3135
+ :tCHARACTER, 'a', [4, 6])
3102
3136
  end
3103
3137
 
3104
3138
  def test_bug_nonlabel_context__18
@@ -3107,57 +3141,57 @@ class TestLexer < Minitest::Test
3107
3141
 
3108
3142
  @lex.static_env = env
3109
3143
  assert_scanned("1+a:a",
3110
- :tINTEGER, 1,
3111
- :tPLUS, '+',
3112
- :tIDENTIFIER, 'a',
3113
- :tCOLON, ':',
3114
- :tIDENTIFIER, 'a')
3144
+ :tINTEGER, 1, [0, 1],
3145
+ :tPLUS, '+', [1, 2],
3146
+ :tIDENTIFIER, 'a', [2, 3],
3147
+ :tCOLON, ':', [3, 4],
3148
+ :tIDENTIFIER, 'a', [4, 5])
3115
3149
  end
3116
3150
 
3117
3151
  def test_bug_string_percent_newline
3118
3152
  assert_scanned(%Q{%\nfoo\n},
3119
- :tSTRING_BEG, "%\n",
3120
- :tSTRING_CONTENT, 'foo',
3121
- :tSTRING_END, "\n")
3153
+ :tSTRING_BEG, "%\n", [0, 2],
3154
+ :tSTRING_CONTENT, 'foo', [2, 5],
3155
+ :tSTRING_END, "\n", [5, 6])
3122
3156
  end
3123
3157
 
3124
3158
  def test_bug_string_percent_zero
3125
3159
  assert_scanned(%Q{%\0foo\0},
3126
- :tSTRING_BEG, "%\0",
3127
- :tSTRING_CONTENT, 'foo',
3128
- :tSTRING_END, "\0")
3160
+ :tSTRING_BEG, "%\0", [0, 2],
3161
+ :tSTRING_CONTENT, 'foo', [2, 5],
3162
+ :tSTRING_END, "\0", [5, 6])
3129
3163
  end
3130
3164
 
3131
3165
  def test_bug_string_utf_escape_composition
3132
3166
  assert_scanned(%q{"\xE2\x80\x99"},
3133
- :tSTRING, "\xE2\x80\x99")
3167
+ :tSTRING, "\xE2\x80\x99", [0, 14])
3134
3168
 
3135
3169
  if defined?(Encoding)
3136
3170
  assert_scanned(%q{"\xE2\x80\x99"}.force_encoding(Encoding::UTF_8),
3137
- :tSTRING, '’'.force_encoding(Encoding::UTF_8))
3171
+ :tSTRING, '’'.force_encoding(Encoding::UTF_8), [0, 14])
3138
3172
  assert_scanned(%q{"\342\200\231"}.force_encoding(Encoding::UTF_8),
3139
- :tSTRING, '’'.force_encoding(Encoding::UTF_8))
3173
+ :tSTRING, '’'.force_encoding(Encoding::UTF_8), [0, 14])
3140
3174
  assert_scanned(%q{"\M-b\C-\M-@\C-\M-Y"}.force_encoding(Encoding::UTF_8),
3141
- :tSTRING, '’'.force_encoding(Encoding::UTF_8))
3175
+ :tSTRING, '’'.force_encoding(Encoding::UTF_8), [0, 20])
3142
3176
  end
3143
3177
  end
3144
3178
 
3145
3179
  def test_bug_string_non_utf
3146
3180
  assert_scanned(%Q{"caf\xE9"},
3147
- :tSTRING, "caf\xE9")
3181
+ :tSTRING, "caf\xE9", [0, 6])
3148
3182
  assert_scanned(%Q{"caf\xC3\xA9"},
3149
- :tSTRING, "caf\xC3\xA9")
3183
+ :tSTRING, "caf\xC3\xA9", [0, 7])
3150
3184
 
3151
3185
  if defined?(Encoding)
3152
3186
  assert_scanned(%q{"café"}.force_encoding(Encoding::UTF_8),
3153
- :tSTRING, "café".force_encoding(Encoding::UTF_8))
3187
+ :tSTRING, "café".force_encoding(Encoding::UTF_8), [0, 6])
3154
3188
  end
3155
3189
  end
3156
3190
 
3157
3191
  def test_bug_semi__END__
3158
3192
  assert_scanned(%Q{foo;\n__END__},
3159
- :tIDENTIFIER, 'foo',
3160
- :tSEMI, ';')
3193
+ :tIDENTIFIER, 'foo', [0, 3],
3194
+ :tSEMI, ';', [3, 4])
3161
3195
  end
3162
3196
 
3163
3197
  def test_bug_eql_end
@@ -3167,87 +3201,87 @@ class TestLexer < Minitest::Test
3167
3201
  def test_bug_hidden_eof
3168
3202
  @lex.state = :expr_beg
3169
3203
  assert_scanned(%Q{"foo\0\x1a\x04bar"},
3170
- :tSTRING_BEG, '"',
3171
- :tSTRING_CONTENT, "foo\0",
3172
- :tSTRING_CONTENT, "\x1a",
3173
- :tSTRING_CONTENT, "\x04",
3174
- :tSTRING_CONTENT, "bar",
3175
- :tSTRING_END, '"')
3204
+ :tSTRING_BEG, '"', [0, 1],
3205
+ :tSTRING_CONTENT, "foo\0", [1, 5],
3206
+ :tSTRING_CONTENT, "\x1a", [5, 6],
3207
+ :tSTRING_CONTENT, "\x04", [6, 7],
3208
+ :tSTRING_CONTENT, "bar", [7, 10],
3209
+ :tSTRING_END, '"', [10, 11])
3176
3210
 
3177
3211
  @lex.state = :expr_beg
3178
3212
  assert_scanned(%Q{'foo\0\x1a\x04bar'},
3179
- :tSTRING_BEG, "'",
3180
- :tSTRING_CONTENT, "foo\0",
3181
- :tSTRING_CONTENT, "\x1a",
3182
- :tSTRING_CONTENT, "\x04",
3183
- :tSTRING_CONTENT, "bar",
3184
- :tSTRING_END, "'")
3213
+ :tSTRING_BEG, "'", [0, 1],
3214
+ :tSTRING_CONTENT, "foo\0", [1, 5],
3215
+ :tSTRING_CONTENT, "\x1a", [5, 6],
3216
+ :tSTRING_CONTENT, "\x04", [6, 7],
3217
+ :tSTRING_CONTENT, "bar", [7, 10],
3218
+ :tSTRING_END, "'", [10, 11])
3185
3219
 
3186
3220
  @lex.state = :expr_beg
3187
3221
  assert_scanned(%Q{%w[foo\0\x1a\x04bar]},
3188
- :tQWORDS_BEG, '%w[',
3189
- :tSTRING_CONTENT, "foo\0",
3190
- :tSTRING_CONTENT, "\x1a",
3191
- :tSTRING_CONTENT, "\x04",
3192
- :tSTRING_CONTENT, "bar",
3193
- :tSPACE, nil,
3194
- :tSTRING_END, ']')
3222
+ :tQWORDS_BEG, '%w[', [0, 3],
3223
+ :tSTRING_CONTENT, "foo\0", [3, 7],
3224
+ :tSTRING_CONTENT, "\x1a", [7, 8],
3225
+ :tSTRING_CONTENT, "\x04", [8, 9],
3226
+ :tSTRING_CONTENT, "bar", [9, 12],
3227
+ :tSPACE, nil, [12, 12],
3228
+ :tSTRING_END, ']', [12, 13])
3195
3229
 
3196
3230
  @lex.state = :expr_beg
3197
3231
  assert_scanned(%Q{%W[foo\0\x1a\x04bar]},
3198
- :tWORDS_BEG, '%W[',
3199
- :tSTRING_CONTENT, "foo\0",
3200
- :tSTRING_CONTENT, "\x1a",
3201
- :tSTRING_CONTENT, "\x04",
3202
- :tSTRING_CONTENT, "bar",
3203
- :tSPACE, nil,
3204
- :tSTRING_END, ']')
3232
+ :tWORDS_BEG, '%W[', [0, 3],
3233
+ :tSTRING_CONTENT, "foo\0", [3, 7],
3234
+ :tSTRING_CONTENT, "\x1a", [7, 8],
3235
+ :tSTRING_CONTENT, "\x04", [8, 9],
3236
+ :tSTRING_CONTENT, "bar", [9, 12],
3237
+ :tSPACE, nil, [12, 12],
3238
+ :tSTRING_END, ']', [12, 13])
3205
3239
 
3206
3240
  @lex.state = :expr_beg
3207
3241
  assert_scanned(%Q{# foo\0\nbar},
3208
- :tIDENTIFIER, 'bar')
3242
+ :tIDENTIFIER, 'bar', [7, 10])
3209
3243
 
3210
3244
  @lex.state = :line_begin
3211
3245
  assert_scanned(%Q{=begin\n\0\n=end\nbar},
3212
- :tIDENTIFIER, 'bar')
3246
+ :tIDENTIFIER, 'bar', [14, 17])
3213
3247
  end
3214
3248
 
3215
3249
  def test_bug_num_adj_kw
3216
- assert_scanned(%q{1if},
3217
- :tINTEGER, 1,
3218
- :kIF_MOD, 'if')
3250
+ assert_scanned('1if',
3251
+ :tINTEGER, 1, [0, 1],
3252
+ :kIF_MOD, 'if', [1, 3])
3219
3253
 
3220
- assert_scanned(%q{1.0if},
3221
- :tFLOAT, 1.0,
3222
- :kIF_MOD, 'if')
3254
+ assert_scanned('1.0if',
3255
+ :tFLOAT, 1.0, [0, 3],
3256
+ :kIF_MOD, 'if', [3, 5])
3223
3257
  end
3224
3258
 
3225
3259
  if defined?(Encoding)
3226
3260
  def test_bug_unicode_in_literal
3227
3261
  setup_lexer(19)
3228
3262
  assert_scanned('"\u00a4"',
3229
- :tSTRING, "\u00a4")
3263
+ :tSTRING, "\u00a4", [0, 8])
3230
3264
  end
3231
3265
 
3232
3266
  def test_bug_utf32le_leak
3233
3267
  setup_lexer(19)
3234
3268
  @lex.force_utf32 = true
3235
3269
  assert_scanned('"F0"',
3236
- :tSTRING, "F0")
3270
+ :tSTRING, "F0", [0, 4])
3237
3271
  end
3238
3272
  end
3239
3273
 
3240
3274
  def test_bug_ragel_stack
3241
3275
  assert_scanned("\"\#{$2 ? $2 : 1}\"",
3242
- :tSTRING_BEG, "\"",
3243
- :tSTRING_DBEG, "\#{",
3244
- :tNTH_REF, 2,
3245
- :tEH, "?",
3246
- :tNTH_REF, 2,
3247
- :tCOLON, ":",
3248
- :tINTEGER, 1,
3249
- :tRCURLY, "}",
3250
- :tSTRING_END, "\"")
3276
+ :tSTRING_BEG, "\"", [0, 1],
3277
+ :tSTRING_DBEG, "\#{", [1, 3],
3278
+ :tNTH_REF, 2, [3, 5],
3279
+ :tEH, "?", [6, 7],
3280
+ :tNTH_REF, 2, [8, 10],
3281
+ :tCOLON, ":", [11, 12],
3282
+ :tINTEGER, 1, [13, 14],
3283
+ :tRCURLY, "}", [14, 15],
3284
+ :tSTRING_END, "\"", [15, 16])
3251
3285
  end
3252
3286
 
3253
3287
  end