parser 2.6.5.0 → 2.7.2.0

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