parser 2.4.0.2 → 2.5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -6
  3. data/CHANGELOG.md +35 -1
  4. data/Gemfile +2 -0
  5. data/README.md +1 -2
  6. data/Rakefile +2 -1
  7. data/bin/ruby-parse +2 -1
  8. data/bin/ruby-rewrite +2 -1
  9. data/lib/gauntlet_parser.rb +2 -0
  10. data/lib/parser.rb +16 -17
  11. data/lib/parser/all.rb +2 -0
  12. data/lib/parser/ast/node.rb +2 -0
  13. data/lib/parser/ast/processor.rb +2 -0
  14. data/lib/parser/base.rb +6 -12
  15. data/lib/parser/builders/default.rb +28 -47
  16. data/lib/parser/clobbering_error.rb +2 -0
  17. data/lib/parser/context.rb +42 -0
  18. data/lib/parser/current.rb +4 -20
  19. data/lib/parser/deprecation.rb +13 -0
  20. data/lib/parser/diagnostic.rb +3 -3
  21. data/lib/parser/diagnostic/engine.rb +2 -0
  22. data/lib/parser/lexer.rl +122 -60
  23. data/lib/parser/lexer/dedenter.rb +2 -0
  24. data/lib/parser/lexer/explanation.rb +2 -0
  25. data/lib/parser/lexer/literal.rb +4 -9
  26. data/lib/parser/lexer/stack_state.rb +4 -1
  27. data/lib/parser/macruby.y +32 -17
  28. data/lib/parser/messages.rb +14 -0
  29. data/lib/parser/meta.rb +2 -0
  30. data/lib/parser/rewriter.rb +30 -44
  31. data/lib/parser/ruby18.y +20 -13
  32. data/lib/parser/ruby19.y +32 -17
  33. data/lib/parser/ruby20.y +33 -18
  34. data/lib/parser/ruby21.y +32 -17
  35. data/lib/parser/ruby22.y +32 -17
  36. data/lib/parser/ruby23.y +32 -17
  37. data/lib/parser/ruby24.y +63 -46
  38. data/lib/parser/ruby25.y +72 -48
  39. data/lib/parser/rubymotion.y +33 -18
  40. data/lib/parser/runner.rb +4 -7
  41. data/lib/parser/runner/ruby_parse.rb +10 -0
  42. data/lib/parser/runner/ruby_rewrite.rb +2 -0
  43. data/lib/parser/source/buffer.rb +19 -24
  44. data/lib/parser/source/comment.rb +2 -0
  45. data/lib/parser/source/comment/associator.rb +2 -0
  46. data/lib/parser/source/map.rb +2 -0
  47. data/lib/parser/source/map/collection.rb +2 -0
  48. data/lib/parser/source/map/condition.rb +2 -0
  49. data/lib/parser/source/map/constant.rb +2 -0
  50. data/lib/parser/source/map/definition.rb +2 -0
  51. data/lib/parser/source/map/for.rb +2 -0
  52. data/lib/parser/source/map/heredoc.rb +2 -0
  53. data/lib/parser/source/map/keyword.rb +2 -0
  54. data/lib/parser/source/map/objc_kwarg.rb +2 -0
  55. data/lib/parser/source/map/operator.rb +2 -0
  56. data/lib/parser/source/map/rescue_body.rb +2 -0
  57. data/lib/parser/source/map/send.rb +2 -0
  58. data/lib/parser/source/map/ternary.rb +2 -0
  59. data/lib/parser/source/map/variable.rb +2 -0
  60. data/lib/parser/source/range.rb +81 -13
  61. data/lib/parser/source/rewriter.rb +48 -10
  62. data/lib/parser/source/rewriter/action.rb +2 -0
  63. data/lib/parser/source/tree_rewriter.rb +301 -0
  64. data/lib/parser/source/tree_rewriter/action.rb +133 -0
  65. data/lib/parser/static_environment.rb +2 -0
  66. data/lib/parser/syntax_error.rb +2 -0
  67. data/lib/parser/tree_rewriter.rb +133 -0
  68. data/lib/parser/version.rb +3 -1
  69. data/parser.gemspec +4 -1
  70. data/test/bug_163/fixtures/input.rb +2 -0
  71. data/test/bug_163/fixtures/output.rb +2 -0
  72. data/test/bug_163/rewriter.rb +2 -0
  73. data/test/helper.rb +7 -7
  74. data/test/parse_helper.rb +57 -10
  75. data/test/racc_coverage_helper.rb +2 -0
  76. data/test/test_base.rb +2 -0
  77. data/test/test_current.rb +2 -4
  78. data/test/test_diagnostic.rb +3 -1
  79. data/test/test_diagnostic_engine.rb +2 -0
  80. data/test/test_encoding.rb +61 -49
  81. data/test/test_lexer.rb +164 -77
  82. data/test/test_lexer_stack_state.rb +2 -0
  83. data/test/test_parse_helper.rb +8 -8
  84. data/test/test_parser.rb +613 -51
  85. data/test/test_runner_rewrite.rb +47 -0
  86. data/test/test_source_buffer.rb +22 -10
  87. data/test/test_source_comment.rb +2 -0
  88. data/test/test_source_comment_associator.rb +2 -0
  89. data/test/test_source_map.rb +2 -0
  90. data/test/test_source_range.rb +92 -45
  91. data/test/test_source_rewriter.rb +3 -1
  92. data/test/test_source_rewriter_action.rb +2 -0
  93. data/test/test_source_tree_rewriter.rb +177 -0
  94. data/test/test_static_environment.rb +2 -0
  95. data/test/using_tree_rewriter/fixtures/input.rb +3 -0
  96. data/test/using_tree_rewriter/fixtures/output.rb +3 -0
  97. data/test/using_tree_rewriter/using_tree_rewriter.rb +9 -0
  98. metadata +21 -10
  99. data/lib/parser/compatibility/ruby1_8.rb +0 -20
  100. data/lib/parser/compatibility/ruby1_9.rb +0 -32
  101. data/test/bug_163/test_runner_rewrite.rb +0 -35
@@ -1,4 +1,5 @@
1
1
  # encoding: ascii-8bit
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'helper'
4
5
  require 'complex'
@@ -22,11 +23,7 @@ class TestLexer < Minitest::Test
22
23
  #
23
24
 
24
25
  def utf(str)
25
- if str.respond_to?(:force_encoding)
26
- str.force_encoding(Encoding::UTF_8)
27
- else
28
- str
29
- end
26
+ str.dup.force_encoding(Encoding::UTF_8)
30
27
  end
31
28
 
32
29
  #
@@ -42,20 +39,14 @@ class TestLexer < Minitest::Test
42
39
  def assert_escape(expected, input)
43
40
  source_buffer = Parser::Source::Buffer.new('(assert_escape)')
44
41
 
45
- if defined?(Encoding)
46
- source_buffer.source = "\"\\#{input}\"".encode(input.encoding)
47
- else
48
- source_buffer.source = "\"\\#{input}\""
49
- end
42
+ source_buffer.source = "\"\\#{input}\"".encode(input.encoding)
50
43
 
51
44
  @lex.reset
52
45
  @lex.source_buffer = source_buffer
53
46
 
54
47
  lex_token, (lex_value, *) = @lex.advance
55
48
 
56
- if lex_value.respond_to?(:force_encoding)
57
- lex_value.force_encoding(Encoding::BINARY)
58
- end
49
+ lex_value.force_encoding(Encoding::BINARY)
59
50
 
60
51
  assert_equal [:tSTRING, expected],
61
52
  [lex_token, lex_value],
@@ -156,23 +147,19 @@ class TestLexer < Minitest::Test
156
147
  end
157
148
 
158
149
  def test_read_escape_unicode__19
159
- if RUBY_VERSION >= '1.9'
160
- assert_escape "\x09", 'u{9}'
161
- assert_escape "\x31", 'u{31}'
162
- assert_escape "\x09\x01", 'u{9 1}'
150
+ assert_escape "\x09", 'u{9}'
151
+ assert_escape "\x31", 'u{31}'
152
+ assert_escape "\x09\x01", 'u{9 1}'
163
153
 
164
- assert_escape "\xc4\xa3", utf('u0123')
165
- assert_escape "\xc4\xa3\xc3\xb0\xeb\x84\xa3", utf('u{123 f0 B123}')
166
- end
154
+ assert_escape "\xc4\xa3", utf('u0123')
155
+ assert_escape "\xc4\xa3\xc3\xb0\xeb\x84\xa3", utf('u{123 f0 B123}')
167
156
  end
168
157
 
169
158
  def test_read_escape_unicode_bad__19
170
- if RUBY_VERSION >= '1.9'
171
- refute_escape 'u123'
172
- refute_escape 'u{}'
173
- refute_escape 'u{123 f0h}'
174
- refute_escape 'u{123 f0'
175
- end
159
+ refute_escape 'u123'
160
+ refute_escape 'u{}'
161
+ refute_escape 'u{123 f0h}'
162
+ refute_escape 'u{123 f0'
176
163
  end
177
164
 
178
165
  def test_ambiguous_uminus
@@ -974,6 +961,34 @@ class TestLexer < Minitest::Test
974
961
  :tNL, nil, [8, 9])
975
962
  end
976
963
 
964
+ def test_heredoc_with_identifier_ending_newline__19
965
+ setup_lexer 19
966
+ refute_scanned "<<\"EOS\n\"\n123\nEOS\n"
967
+ end
968
+
969
+ def test_heredoc_with_identifier_ending_newline__24
970
+ setup_lexer 24
971
+
972
+ assert_scanned("a = <<\"EOS\n\"\nABCDEF\nEOS\n",
973
+ :tIDENTIFIER, "a", [0, 1],
974
+ :tEQL, "=", [2, 3],
975
+ :tSTRING_BEG, "<<\"", [4, 12],
976
+ :tSTRING_CONTENT, "ABCDEF\n", [13, 20],
977
+ :tSTRING_END, "EOS", [20, 23],
978
+ :tNL, nil, [12, 13])
979
+ end
980
+
981
+ def test_heredoc_with_identifier_containing_newline_inside__19
982
+ setup_lexer 19
983
+ refute_scanned "<<\"EOS\nEOS\"\n123\nEOS\n"
984
+ end
985
+
986
+ def test_heredoc_with_identifier_containing_newline_inside__24
987
+ setup_lexer 24
988
+
989
+ refute_scanned "<<\"EOS\nEOS\"\n123\nEOS\n"
990
+ end
991
+
977
992
  def test_identifier
978
993
  assert_scanned("identifier",
979
994
  :tIDENTIFIER, "identifier", [0, 10])
@@ -1171,20 +1186,16 @@ class TestLexer < Minitest::Test
1171
1186
  end
1172
1187
 
1173
1188
  def test_question_eh_escape_u_4_digits
1174
- if RUBY_VERSION >= '1.9'
1175
- setup_lexer 19
1176
- assert_scanned '?\\u0001', :tCHARACTER, "\u0001", [0, 7]
1177
- end
1189
+ setup_lexer 19
1190
+ assert_scanned '?\\u0001', :tCHARACTER, "\u0001", [0, 7]
1178
1191
  end
1179
1192
 
1180
1193
  def test_question_eh_single_unicode_point
1181
- if RUBY_VERSION >= '1.9'
1182
- setup_lexer 19
1183
- assert_scanned '?\\u{123}', :tCHARACTER, "\u0123", [0, 8]
1194
+ setup_lexer 19
1195
+ assert_scanned '?\\u{123}', :tCHARACTER, "\u0123", [0, 8]
1184
1196
 
1185
- setup_lexer 19
1186
- assert_scanned '?\\u{a}', :tCHARACTER, "\n", [0, 6]
1187
- end
1197
+ setup_lexer 19
1198
+ assert_scanned '?\\u{a}', :tCHARACTER, "\n", [0, 6]
1188
1199
  end
1189
1200
 
1190
1201
  def test_question_eh_multiple_unicode_points
@@ -1201,6 +1212,46 @@ class TestLexer < Minitest::Test
1201
1212
  refute_scanned '?\\u{123'
1202
1213
  end
1203
1214
 
1215
+ def test_question_eh_escape_space_around_unicode_point__19
1216
+ setup_lexer 19
1217
+ refute_scanned '"\\u{1 }"'
1218
+
1219
+ setup_lexer 19
1220
+ refute_scanned '"\\u{ 1}"'
1221
+
1222
+ setup_lexer 19
1223
+ refute_scanned '"\\u{ 1 }"'
1224
+
1225
+ setup_lexer 19
1226
+ refute_scanned '"\\u{1 2 }"'
1227
+
1228
+ setup_lexer 19
1229
+ refute_scanned '"\\u{ 1 2}"'
1230
+
1231
+ setup_lexer 19
1232
+ refute_scanned '"\\u{1 2}"'
1233
+ end
1234
+
1235
+ def test_question_eh_escape_space_around_unicode_point__24
1236
+ setup_lexer 24
1237
+ assert_scanned '"\\u{ 1}"', :tSTRING, "\u0001", [0, 8]
1238
+
1239
+ setup_lexer 24
1240
+ assert_scanned '"\\u{1 }"', :tSTRING, "\u0001", [0, 8]
1241
+
1242
+ setup_lexer 24
1243
+ assert_scanned '"\\u{ 1 }"', :tSTRING, "\u0001", [0, 9]
1244
+
1245
+ setup_lexer 24
1246
+ assert_scanned '"\\u{1 2 }"', :tSTRING, "\u0001\u0002", [0, 10]
1247
+
1248
+ setup_lexer 24
1249
+ assert_scanned '"\\u{ 1 2}"', :tSTRING, "\u0001\u0002", [0, 10]
1250
+
1251
+ setup_lexer 24
1252
+ assert_scanned '"\\u{1 2}"', :tSTRING, "\u0001\u0002", [0, 10]
1253
+ end
1254
+
1204
1255
  def test_integer_hex
1205
1256
  assert_scanned "0x2a", :tINTEGER, 42, [0, 4]
1206
1257
  end
@@ -2836,19 +2887,17 @@ class TestLexer < Minitest::Test
2836
2887
  # Handling of encoding-related issues.
2837
2888
  #
2838
2889
 
2839
- if defined?(Encoding)
2840
- def test_transcoded_source_is_converted_back_to_original_encoding
2841
- setup_lexer(19)
2842
- @lex.force_utf32 = true
2843
- @lex.tokens = []
2844
- assert_scanned(utf('"a" + "b"'),
2845
- :tSTRING, "a", [0, 3],
2846
- :tPLUS, "+", [4, 5],
2847
- :tSTRING, "b", [6, 9])
2848
-
2849
- @lex.tokens.each do |_type, (str, _range)|
2850
- assert_equal Encoding::UTF_8, str.encoding
2851
- end
2890
+ def test_transcoded_source_is_converted_back_to_original_encoding
2891
+ setup_lexer(19)
2892
+ @lex.force_utf32 = true
2893
+ @lex.tokens = []
2894
+ assert_scanned(utf('"a" + "b"'),
2895
+ :tSTRING, "a", [0, 3],
2896
+ :tPLUS, "+", [4, 5],
2897
+ :tSTRING, "b", [6, 9])
2898
+
2899
+ @lex.tokens.each do |_type, (str, _range)|
2900
+ assert_equal Encoding::UTF_8, str.encoding
2852
2901
  end
2853
2902
  end
2854
2903
 
@@ -3286,21 +3335,17 @@ class TestLexer < Minitest::Test
3286
3335
  assert_scanned(%q{"\xE2\x80\x99"},
3287
3336
  :tSTRING, "\xE2\x80\x99", [0, 14])
3288
3337
 
3289
- if defined?(Encoding)
3290
- assert_scanned(utf(%q{"\xE2\x80\x99"}),
3291
- :tSTRING, utf('’'), [0, 14])
3292
- assert_scanned(utf(%q{"\342\200\231"}),
3293
- :tSTRING, utf('’'), [0, 14])
3294
- assert_scanned(utf(%q{"\M-b\C-\M-@\C-\M-Y"}),
3295
- :tSTRING, utf('’'), [0, 20])
3296
- end
3338
+ assert_scanned(utf(%q{"\xE2\x80\x99"}),
3339
+ :tSTRING, utf('’'), [0, 14])
3340
+ assert_scanned(utf(%q{"\342\200\231"}),
3341
+ :tSTRING, utf('’'), [0, 14])
3342
+ assert_scanned(utf(%q{"\M-b\C-\M-@\C-\M-Y"}),
3343
+ :tSTRING, utf('’'), [0, 20])
3297
3344
  end
3298
3345
 
3299
3346
  def test_bug_string_utf_escape_noop
3300
- if defined?(Encoding)
3301
- assert_scanned(utf(%q{"\あ"}),
3302
- :tSTRING, utf("あ"), [0, 4])
3303
- end
3347
+ assert_scanned(utf(%q{"\あ"}),
3348
+ :tSTRING, utf(""), [0, 4])
3304
3349
  end
3305
3350
 
3306
3351
  def test_bug_string_non_utf
@@ -3309,10 +3354,8 @@ class TestLexer < Minitest::Test
3309
3354
  assert_scanned(%Q{"caf\xC3\xA9"},
3310
3355
  :tSTRING, "caf\xC3\xA9", [0, 7])
3311
3356
 
3312
- if defined?(Encoding)
3313
- assert_scanned(utf(%q{"café"}),
3314
- :tSTRING, utf("café"), [0, 6])
3315
- end
3357
+ assert_scanned(utf(%q{"café"}),
3358
+ :tSTRING, utf("café"), [0, 6])
3316
3359
  end
3317
3360
 
3318
3361
  def test_bug_semi__END__
@@ -3383,19 +3426,17 @@ class TestLexer < Minitest::Test
3383
3426
  :kIF_MOD, 'if', [3, 5])
3384
3427
  end
3385
3428
 
3386
- if defined?(Encoding)
3387
- def test_bug_unicode_in_literal
3388
- setup_lexer(19)
3389
- assert_scanned('"\u00a4"',
3390
- :tSTRING, "\u00a4", [0, 8])
3391
- end
3429
+ def test_bug_unicode_in_literal
3430
+ setup_lexer(19)
3431
+ assert_scanned('"\u00a4"',
3432
+ :tSTRING, "\u00a4", [0, 8])
3433
+ end
3392
3434
 
3393
- def test_bug_utf32le_leak
3394
- setup_lexer(19)
3395
- @lex.force_utf32 = true
3396
- assert_scanned('"F0"',
3397
- :tSTRING, "F0", [0, 4])
3398
- end
3435
+ def test_bug_utf32le_leak
3436
+ setup_lexer(19)
3437
+ @lex.force_utf32 = true
3438
+ assert_scanned('"F0"',
3439
+ :tSTRING, "F0", [0, 4])
3399
3440
  end
3400
3441
 
3401
3442
  def test_bug_ragel_stack
@@ -3411,4 +3452,50 @@ class TestLexer < Minitest::Test
3411
3452
  :tSTRING_END, "\"", [15, 16])
3412
3453
  end
3413
3454
 
3455
+ def test_bug_423
3456
+ @lex.state = :expr_beg
3457
+ assert_scanned(':&&',
3458
+ :tSYMBEG, ':', [0, 1],
3459
+ :tANDOP, '&&', [1, 3])
3460
+
3461
+ @lex.state = :expr_beg
3462
+ assert_scanned(':||',
3463
+ :tSYMBEG, ':', [0, 1],
3464
+ :tOROP, '||', [1, 3])
3465
+ end
3466
+
3467
+ def test_bug_418
3468
+ setup_lexer 19
3469
+
3470
+ assert_scanned("{\n=begin\nx: 1,\n=end\ny: 2}",
3471
+ :tLBRACE, '{', [0, 1],
3472
+ :tLABEL, 'y', [20, 22],
3473
+ :tINTEGER, 2, [23, 24],
3474
+ :tRCURLY, '}', [24, 25])
3475
+ end
3476
+
3477
+ def test_bug_407
3478
+ setup_lexer(21)
3479
+
3480
+ assert_scanned('123if cond',
3481
+ :tINTEGER, 123, [0, 3],
3482
+ :kIF_MOD, 'if', [3, 5],
3483
+ :tIDENTIFIER, 'cond', [6, 10])
3484
+
3485
+ assert_scanned('1.23if cond',
3486
+ :tFLOAT, 1.23, [0, 4],
3487
+ :kIF_MOD, 'if', [4, 6],
3488
+ :tIDENTIFIER, 'cond', [7, 11])
3489
+
3490
+ assert_scanned('123rescue cond',
3491
+ :tINTEGER, 123, [0, 3],
3492
+ :kRESCUE_MOD, 'rescue', [3, 9],
3493
+ :tIDENTIFIER, 'cond', [10, 14])
3494
+
3495
+ assert_scanned('1.23rescue cond',
3496
+ :tFLOAT, 1.23, [0, 4],
3497
+ :kRESCUE_MOD, 'rescue', [4, 10],
3498
+ :tIDENTIFIER, 'cond', [11, 15])
3499
+ end
3500
+
3414
3501
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'helper'
2
4
 
3
5
  class TestLexerStackState < Minitest::Test
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'helper'
2
4
  require 'parse_helper'
3
5
 
@@ -8,16 +10,14 @@ class TestParseHelper < Minitest::Test
8
10
  assert_instance_of Parser::Ruby18,
9
11
  parser_for_ruby_version('1.8')
10
12
 
11
- unless RUBY_VERSION == '1.8.7'
12
- assert_instance_of Parser::Ruby19,
13
- parser_for_ruby_version('1.9')
13
+ assert_instance_of Parser::Ruby19,
14
+ parser_for_ruby_version('1.9')
14
15
 
15
- assert_instance_of Parser::Ruby20,
16
- parser_for_ruby_version('2.0')
16
+ assert_instance_of Parser::Ruby20,
17
+ parser_for_ruby_version('2.0')
17
18
 
18
- assert_instance_of Parser::Ruby21,
19
- parser_for_ruby_version('2.1')
20
- end
19
+ assert_instance_of Parser::Ruby21,
20
+ parser_for_ruby_version('2.1')
21
21
  end
22
22
 
23
23
  def parse_maps(what)
@@ -1,4 +1,5 @@
1
- # encoding:utf-8
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'helper'
4
5
  require 'parse_helper'
@@ -1102,6 +1103,21 @@ class TestParser < Minitest::Test
1102
1103
  [:error, :dynamic_const],
1103
1104
  %q{def f; ::Bar = 1; end},
1104
1105
  %q{ ~~~~~ location})
1106
+
1107
+ assert_diagnoses(
1108
+ [:error, :dynamic_const],
1109
+ %q{def self.f; Foo = 1; end},
1110
+ %q{ ~~~ location})
1111
+
1112
+ assert_diagnoses(
1113
+ [:error, :dynamic_const],
1114
+ %q{def self.f; Foo::Bar = 1; end},
1115
+ %q{ ~~~~~~~~ location})
1116
+
1117
+ assert_diagnoses(
1118
+ [:error, :dynamic_const],
1119
+ %q{def self.f; ::Bar = 1; end},
1120
+ %q{ ~~~~~ location})
1105
1121
  end
1106
1122
 
1107
1123
  # Multiple assignment
@@ -1732,6 +1748,11 @@ class TestParser < Minitest::Test
1732
1748
  [:error, :class_in_def],
1733
1749
  %q{def a; class Foo; end; end},
1734
1750
  %q{ ^^^^^ location})
1751
+
1752
+ assert_diagnoses(
1753
+ [:error, :class_in_def],
1754
+ %q{def self.a; class Foo; end; end},
1755
+ %q{ ^^^^^ location})
1735
1756
  end
1736
1757
 
1737
1758
  def test_sclass
@@ -5204,39 +5225,37 @@ class TestParser < Minitest::Test
5204
5225
  end
5205
5226
  end
5206
5227
 
5207
- if defined?(Encoding)
5208
- def test_bom
5209
- assert_parses(
5210
- s(:int, 1),
5211
- %Q{\xef\xbb\xbf1}.force_encoding(Encoding::BINARY),
5212
- %q{},
5213
- %w(1.9 2.0 2.1))
5214
- end
5228
+ def test_bom
5229
+ assert_parses(
5230
+ s(:int, 1),
5231
+ %Q{\xef\xbb\xbf1}.dup.force_encoding(Encoding::BINARY),
5232
+ %q{},
5233
+ %w(1.9 2.0 2.1))
5234
+ end
5215
5235
 
5216
- def test_magic_encoding_comment
5217
- assert_parses(
5218
- s(:begin,
5219
- s(:lvasgn, :"проверка", s(:int, 42)),
5220
- s(:send, nil, :puts, s(:lvar, :"проверка"))),
5221
- %Q{# coding:koi8-r
5222
- \xd0\xd2\xcf\xd7\xc5\xd2\xcb\xc1 = 42
5223
- puts \xd0\xd2\xcf\xd7\xc5\xd2\xcb\xc1}.
5224
- force_encoding(Encoding::BINARY),
5225
- %q{},
5226
- %w(1.9 2.0 2.1))
5227
- end
5236
+ def test_magic_encoding_comment
5237
+ assert_parses(
5238
+ s(:begin,
5239
+ s(:lvasgn, :"проверка", s(:int, 42)),
5240
+ s(:send, nil, :puts, s(:lvar, :"проверка"))),
5241
+ %Q{# coding:koi8-r
5242
+ \xd0\xd2\xcf\xd7\xc5\xd2\xcb\xc1 = 42
5243
+ puts \xd0\xd2\xcf\xd7\xc5\xd2\xcb\xc1}.dup.
5244
+ force_encoding(Encoding::BINARY),
5245
+ %q{},
5246
+ %w(1.9 2.0 2.1))
5247
+ end
5228
5248
 
5229
- def test_regexp_encoding
5230
- assert_parses(
5231
- s(:match_with_lvasgn,
5232
- s(:regexp,
5233
- s(:str, "\\xa8"),
5234
- s(:regopt, :n)),
5235
- s(:str, "")),
5236
- %q{/\xa8/n =~ ""}.force_encoding(Encoding::UTF_8),
5237
- %{},
5238
- SINCE_1_9)
5239
- end
5249
+ def test_regexp_encoding
5250
+ assert_parses(
5251
+ s(:match_with_lvasgn,
5252
+ s(:regexp,
5253
+ s(:str, "\\xa8"),
5254
+ s(:regopt, :n)),
5255
+ s(:str, "")),
5256
+ %q{/\xa8/n =~ ""}.dup.force_encoding(Encoding::UTF_8),
5257
+ %{},
5258
+ SINCE_1_9)
5240
5259
  end
5241
5260
 
5242
5261
  #
@@ -5460,25 +5479,23 @@ class TestParser < Minitest::Test
5460
5479
  end
5461
5480
 
5462
5481
  def test_bug_ascii_8bit_in_literal
5463
- if defined?(Encoding)
5464
- assert_diagnoses(
5465
- [:error, :invalid_encoding],
5466
- %q{".\xc3."},
5467
- %q{^^^^^^^^ location},
5468
- ALL_VERSIONS)
5469
-
5470
- assert_diagnoses(
5471
- [:error, :invalid_encoding],
5472
- %q{%W"x .\xc3."},
5473
- %q{ ^^^^^^ location},
5474
- ALL_VERSIONS)
5475
-
5476
- assert_diagnoses(
5477
- [:error, :invalid_encoding],
5478
- %q{:".\xc3."},
5479
- %q{ ^^^^^^ location},
5480
- ALL_VERSIONS)
5481
- end
5482
+ assert_diagnoses(
5483
+ [:error, :invalid_encoding],
5484
+ %q{".\xc3."},
5485
+ %q{^^^^^^^^ location},
5486
+ ALL_VERSIONS)
5487
+
5488
+ assert_diagnoses(
5489
+ [:error, :invalid_encoding],
5490
+ %q{%W"x .\xc3."},
5491
+ %q{ ^^^^^^ location},
5492
+ ALL_VERSIONS)
5493
+
5494
+ assert_diagnoses(
5495
+ [:error, :invalid_encoding],
5496
+ %q{:".\xc3."},
5497
+ %q{ ^^^^^^ location},
5498
+ ALL_VERSIONS)
5482
5499
 
5483
5500
  assert_diagnoses(
5484
5501
  [:error, :invalid_encoding],
@@ -5969,6 +5986,170 @@ class TestParser < Minitest::Test
5969
5986
  %q{ ^^^^^^ location})
5970
5987
  end
5971
5988
 
5989
+ def test_ruby_bug_11873
5990
+ # strings
5991
+ assert_parses(
5992
+ s(:block,
5993
+ s(:send, nil, :a,
5994
+ s(:block,
5995
+ s(:send, nil, :b),
5996
+ s(:args),
5997
+ s(:send, nil, :c, s(:send, nil, :d))),
5998
+ s(:str, "x")),
5999
+ s(:args),
6000
+ nil),
6001
+ %q{a b{c d}, "x" do end},
6002
+ %q{},
6003
+ SINCE_2_4)
6004
+
6005
+ assert_parses(
6006
+ s(:block,
6007
+ s(:send, nil, :a,
6008
+ s(:send, nil, :b,
6009
+ s(:send, nil, :c,
6010
+ s(:send, nil, :d))),
6011
+ s(:str, "x")),
6012
+ s(:args),
6013
+ nil),
6014
+ %q{a b(c d), "x" do end},
6015
+ %q{},
6016
+ SINCE_2_4)
6017
+
6018
+ assert_parses(
6019
+ s(:block,
6020
+ s(:send, nil, :a,
6021
+ s(:block,
6022
+ s(:send, nil, :b),
6023
+ s(:args),
6024
+ s(:send, nil, :c,
6025
+ s(:send, nil, :d))),
6026
+ s(:str, "x")),
6027
+ s(:args), nil),
6028
+ %q{a b{c(d)}, "x" do end},
6029
+ %q{},
6030
+ SINCE_2_4)
6031
+
6032
+ assert_parses(
6033
+ s(:block,
6034
+ s(:send, nil, :a,
6035
+ s(:send, nil, :b,
6036
+ s(:send, nil, :c,
6037
+ s(:send, nil, :d))),
6038
+ s(:str, "x")),
6039
+ s(:args), nil),
6040
+ %q{a b(c(d)), "x" do end},
6041
+ %q{},
6042
+ SINCE_2_4)
6043
+
6044
+ # regexps without options
6045
+ assert_parses(
6046
+ s(:block,
6047
+ s(:send, nil, :a,
6048
+ s(:block,
6049
+ s(:send, nil, :b),
6050
+ s(:args),
6051
+ s(:send, nil, :c, s(:send, nil, :d))),
6052
+ s(:regexp, s(:str, "x"), s(:regopt))),
6053
+ s(:args),
6054
+ nil),
6055
+ %q{a b{c d}, /x/ do end},
6056
+ %q{},
6057
+ SINCE_2_4)
6058
+
6059
+ assert_parses(
6060
+ s(:block,
6061
+ s(:send, nil, :a,
6062
+ s(:send, nil, :b,
6063
+ s(:send, nil, :c,
6064
+ s(:send, nil, :d))),
6065
+ s(:regexp, s(:str, "x"), s(:regopt))),
6066
+ s(:args),
6067
+ nil),
6068
+ %q{a b(c d), /x/ do end},
6069
+ %q{},
6070
+ SINCE_2_4)
6071
+
6072
+ assert_parses(
6073
+ s(:block,
6074
+ s(:send, nil, :a,
6075
+ s(:block,
6076
+ s(:send, nil, :b),
6077
+ s(:args),
6078
+ s(:send, nil, :c,
6079
+ s(:send, nil, :d))),
6080
+ s(:regexp, s(:str, "x"), s(:regopt))),
6081
+ s(:args), nil),
6082
+ %q{a b{c(d)}, /x/ do end},
6083
+ %q{},
6084
+ SINCE_2_4)
6085
+
6086
+ assert_parses(
6087
+ s(:block,
6088
+ s(:send, nil, :a,
6089
+ s(:send, nil, :b,
6090
+ s(:send, nil, :c,
6091
+ s(:send, nil, :d))),
6092
+ s(:regexp, s(:str, "x"), s(:regopt))),
6093
+ s(:args), nil),
6094
+ %q{a b(c(d)), /x/ do end},
6095
+ %q{},
6096
+ SINCE_2_4)
6097
+
6098
+ # regexps with options
6099
+ assert_parses(
6100
+ s(:block,
6101
+ s(:send, nil, :a,
6102
+ s(:block,
6103
+ s(:send, nil, :b),
6104
+ s(:args),
6105
+ s(:send, nil, :c, s(:send, nil, :d))),
6106
+ s(:regexp, s(:str, "x"), s(:regopt, :m))),
6107
+ s(:args),
6108
+ nil),
6109
+ %q{a b{c d}, /x/m do end},
6110
+ %q{},
6111
+ SINCE_2_4)
6112
+
6113
+ assert_parses(
6114
+ s(:block,
6115
+ s(:send, nil, :a,
6116
+ s(:send, nil, :b,
6117
+ s(:send, nil, :c,
6118
+ s(:send, nil, :d))),
6119
+ s(:regexp, s(:str, "x"), s(:regopt, :m))),
6120
+ s(:args),
6121
+ nil),
6122
+ %q{a b(c d), /x/m do end},
6123
+ %q{},
6124
+ SINCE_2_4)
6125
+
6126
+ assert_parses(
6127
+ s(:block,
6128
+ s(:send, nil, :a,
6129
+ s(:block,
6130
+ s(:send, nil, :b),
6131
+ s(:args),
6132
+ s(:send, nil, :c,
6133
+ s(:send, nil, :d))),
6134
+ s(:regexp, s(:str, "x"), s(:regopt, :m))),
6135
+ s(:args), nil),
6136
+ %q{a b{c(d)}, /x/m do end},
6137
+ %q{},
6138
+ SINCE_2_4)
6139
+
6140
+ assert_parses(
6141
+ s(:block,
6142
+ s(:send, nil, :a,
6143
+ s(:send, nil, :b,
6144
+ s(:send, nil, :c,
6145
+ s(:send, nil, :d))),
6146
+ s(:regexp, s(:str, "x"), s(:regopt, :m))),
6147
+ s(:args), nil),
6148
+ %q{a b(c(d)), /x/m do end},
6149
+ %q{},
6150
+ SINCE_2_4)
6151
+ end
6152
+
5972
6153
  def test_parser_bug_198
5973
6154
  assert_parses(
5974
6155
  s(:array,
@@ -6021,4 +6202,385 @@ class TestParser < Minitest::Test
6021
6202
  s(:regexp, s(:str, "#)"), s(:regopt, :x)),
6022
6203
  %Q{/#)/x})
6023
6204
  end
6205
+
6206
+ def test_bug_do_block_in_hash_brace
6207
+ assert_parses(
6208
+ s(:send, nil, :p,
6209
+ s(:sym, :foo),
6210
+ s(:hash,
6211
+ s(:pair,
6212
+ s(:sym, :a),
6213
+ s(:block,
6214
+ s(:send, nil, :proc),
6215
+ s(:args), nil)),
6216
+ s(:pair,
6217
+ s(:sym, :b),
6218
+ s(:block,
6219
+ s(:send, nil, :proc),
6220
+ s(:args), nil)))),
6221
+ %q{p :foo, {a: proc do end, b: proc do end}},
6222
+ %q{},
6223
+ SINCE_2_3)
6224
+
6225
+ assert_parses(
6226
+ s(:send, nil, :p,
6227
+ s(:sym, :foo),
6228
+ s(:hash,
6229
+ s(:pair,
6230
+ s(:sym, :a),
6231
+ s(:block,
6232
+ s(:send, nil, :proc),
6233
+ s(:args), nil)),
6234
+ s(:pair,
6235
+ s(:sym, :b),
6236
+ s(:block,
6237
+ s(:send, nil, :proc),
6238
+ s(:args), nil)))),
6239
+ %q{p :foo, {:a => proc do end, b: proc do end}},
6240
+ %q{},
6241
+ SINCE_2_3)
6242
+
6243
+ assert_parses(
6244
+ s(:send, nil, :p,
6245
+ s(:sym, :foo),
6246
+ s(:hash,
6247
+ s(:pair,
6248
+ s(:sym, :a),
6249
+ s(:block,
6250
+ s(:send, nil, :proc),
6251
+ s(:args), nil)),
6252
+ s(:pair,
6253
+ s(:sym, :b),
6254
+ s(:block,
6255
+ s(:send, nil, :proc),
6256
+ s(:args), nil)))),
6257
+ %q{p :foo, {"a": proc do end, b: proc do end}},
6258
+ %q{},
6259
+ SINCE_2_3)
6260
+
6261
+ assert_parses(
6262
+ s(:send, nil, :p,
6263
+ s(:sym, :foo),
6264
+ s(:hash,
6265
+ s(:pair,
6266
+ s(:block,
6267
+ s(:send, nil, :proc),
6268
+ s(:args), nil),
6269
+ s(:block,
6270
+ s(:send, nil, :proc),
6271
+ s(:args), nil)),
6272
+ s(:pair,
6273
+ s(:sym, :b),
6274
+ s(:block,
6275
+ s(:send, nil, :proc),
6276
+ s(:args), nil)))),
6277
+ %q{p :foo, {proc do end => proc do end, b: proc do end}},
6278
+ %q{},
6279
+ SINCE_2_3)
6280
+
6281
+ assert_parses(
6282
+ s(:send, nil, :p,
6283
+ s(:sym, :foo),
6284
+ s(:hash,
6285
+ s(:kwsplat,
6286
+ s(:block,
6287
+ s(:send, nil, :proc),
6288
+ s(:args), nil)),
6289
+ s(:pair,
6290
+ s(:sym, :b),
6291
+ s(:block,
6292
+ s(:send, nil, :proc),
6293
+ s(:args), nil)))),
6294
+ %q{p :foo, {** proc do end, b: proc do end}},
6295
+ %q{},
6296
+ SINCE_2_3)
6297
+ end
6298
+
6299
+ def test_lparenarg_after_lvar__since_25
6300
+ assert_parses(
6301
+ s(:send, nil, :meth,
6302
+ s(:send,
6303
+ s(:begin,
6304
+ s(:float, -1.3)), :abs)),
6305
+ %q{meth (-1.3).abs},
6306
+ %q{},
6307
+ ALL_VERSIONS - SINCE_2_5)
6308
+
6309
+ assert_parses(
6310
+ s(:send,
6311
+ s(:send, nil, :foo,
6312
+ s(:float, -1.3)), :abs),
6313
+ %q{foo (-1.3).abs},
6314
+ %q{},
6315
+ ALL_VERSIONS - SINCE_2_5)
6316
+
6317
+ assert_parses(
6318
+ s(:send, nil, :meth,
6319
+ s(:send,
6320
+ s(:begin,
6321
+ s(:float, -1.3)), :abs)),
6322
+ %q{meth (-1.3).abs},
6323
+ %q{},
6324
+ SINCE_2_5)
6325
+
6326
+ assert_parses(
6327
+ s(:send, nil, :foo,
6328
+ s(:send,
6329
+ s(:begin,
6330
+ s(:float, -1.3)), :abs)),
6331
+ %q{foo (-1.3).abs},
6332
+ %q{},
6333
+ SINCE_2_5)
6334
+ end
6335
+
6336
+ def test_context_class
6337
+ [
6338
+ %q{class A;},
6339
+ %q{class A < B;}
6340
+ ].each do |code|
6341
+ assert_context([:class], code, ALL_VERSIONS)
6342
+ end
6343
+ end
6344
+
6345
+ def test_context_sclass
6346
+ assert_context(
6347
+ [:sclass],
6348
+ %q{class << foo;},
6349
+ ALL_VERSIONS)
6350
+ end
6351
+
6352
+ def test_context_def
6353
+ assert_context(
6354
+ [:def],
6355
+ %q{def m;},
6356
+ ALL_VERSIONS)
6357
+ end
6358
+
6359
+ def test_context_defs
6360
+ assert_context(
6361
+ [:defs],
6362
+ %q{def foo.m;},
6363
+ ALL_VERSIONS)
6364
+ end
6365
+
6366
+ def test_context_cmd_brace_block
6367
+ [
6368
+ 'tap 1, { 1 => 2 } {',
6369
+ 'foo.tap 1, { 1 => 2 } {',
6370
+ 'foo::tap 1, { 1 => 2 } {'
6371
+ ].each do |code|
6372
+ assert_context([:block], code, ALL_VERSIONS)
6373
+ end
6374
+ end
6375
+
6376
+ def test_context_brace_block
6377
+ [
6378
+ 'tap {',
6379
+ 'foo.tap {',
6380
+ 'foo::tap {',
6381
+ 'tap do',
6382
+ 'foo.tap do',
6383
+ 'foo::tap do'
6384
+ ].each do |code|
6385
+ assert_context([:block], code, ALL_VERSIONS)
6386
+ end
6387
+ end
6388
+
6389
+ def test_context_do_block
6390
+ [
6391
+ %q{tap 1 do},
6392
+ %q{foo.tap do},
6393
+ %q{foo::tap do}
6394
+ ].each do |code|
6395
+ assert_context([:block], code, ALL_VERSIONS)
6396
+ end
6397
+ end
6398
+
6399
+ def test_context_lambda
6400
+ [
6401
+ '->() {',
6402
+ '->() do'
6403
+ ].each do |code|
6404
+ assert_context([:lambda], code, SINCE_1_9)
6405
+ end
6406
+ end
6407
+
6408
+ def test_context_nested
6409
+ assert_context(
6410
+ [:class, :sclass, :defs, :def, :block],
6411
+ %q{class A; class << foo; def bar.m; def m; tap do},
6412
+ ALL_VERSIONS)
6413
+
6414
+ assert_context(
6415
+ [:class, :sclass, :defs, :def, :lambda, :block],
6416
+ %q{class A; class << foo; def bar.m; def m; -> do; tap do},
6417
+ SINCE_1_9)
6418
+
6419
+ assert_context(
6420
+ [],
6421
+ %q{
6422
+ class A
6423
+ class << foo
6424
+ def bar.m
6425
+ def m
6426
+ tap do
6427
+ end
6428
+ end
6429
+ end
6430
+ end
6431
+ end
6432
+ },
6433
+ ALL_VERSIONS)
6434
+
6435
+ assert_context(
6436
+ [],
6437
+ %q{
6438
+ class A
6439
+ class << foo
6440
+ def bar.m
6441
+ def m
6442
+ -> do
6443
+ tap do
6444
+ end
6445
+ end
6446
+ end
6447
+ end
6448
+ end
6449
+ end
6450
+ },
6451
+ SINCE_1_9)
6452
+ end
6453
+
6454
+ def test_return_in_class
6455
+ assert_parses(
6456
+ s(:class,
6457
+ s(:const, nil, :A), nil,
6458
+ s(:return)),
6459
+ %q{class A; return; end},
6460
+ %q{},
6461
+ ALL_VERSIONS - SINCE_2_5)
6462
+
6463
+ assert_diagnoses(
6464
+ [:error, :invalid_return, {}],
6465
+ %q{class A; return; end},
6466
+ %q{ ^^^^^^ location},
6467
+ SINCE_2_5)
6468
+
6469
+ [
6470
+ %q{class << foo; return; end},
6471
+ %q{def m; return; end},
6472
+ %q{tap { return }},
6473
+ %q{class A; class << self; return; end; end},
6474
+ %q{class A; def m; return; end; end},
6475
+ ].each do |code|
6476
+ refute_diagnoses(code, ALL_VERSIONS)
6477
+ end
6478
+
6479
+ [
6480
+ %q{-> do return end},
6481
+ %q{class A; -> do return end; end},
6482
+ ].each do |code|
6483
+ refute_diagnoses(code, SINCE_1_9)
6484
+ end
6485
+ end
6486
+
6487
+ def test_ruby_bug_13547
6488
+ assert_diagnoses(
6489
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6490
+ %q{m "x" {}},
6491
+ %q{ ^ location},
6492
+ SINCE_2_4)
6493
+
6494
+ assert_diagnoses(
6495
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6496
+ %q{m "#{'x'}" {}},
6497
+ %q{ ^ location},
6498
+ SINCE_2_4)
6499
+
6500
+ assert_diagnoses(
6501
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6502
+ %q{m 1 {}},
6503
+ %q{ ^ location},
6504
+ SINCE_2_4)
6505
+
6506
+ assert_diagnoses(
6507
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6508
+ %q{m 1.0 {}},
6509
+ %q{ ^ location},
6510
+ SINCE_2_4)
6511
+
6512
+ assert_diagnoses(
6513
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6514
+ %q{m 1r {}},
6515
+ %q{ ^ location},
6516
+ SINCE_2_4)
6517
+
6518
+ assert_diagnoses(
6519
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6520
+ %q{m 1i {}},
6521
+ %q{ ^ location},
6522
+ SINCE_2_4)
6523
+
6524
+ assert_diagnoses(
6525
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6526
+ %q{m :m {}},
6527
+ %q{ ^ location},
6528
+ SINCE_2_4)
6529
+
6530
+ assert_diagnoses(
6531
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6532
+ %q{m :"#{m}" {}},
6533
+ %q{ ^ location},
6534
+ SINCE_2_4)
6535
+
6536
+ assert_diagnoses(
6537
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6538
+ %q{m %[] {}},
6539
+ %q{ ^ location},
6540
+ SINCE_2_4)
6541
+
6542
+ assert_diagnoses(
6543
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6544
+ %q{m 0..1 {}},
6545
+ %q{ ^ location},
6546
+ SINCE_2_4)
6547
+
6548
+ assert_diagnoses(
6549
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6550
+ %q{m 0...1 {}},
6551
+ %q{ ^ location},
6552
+ SINCE_2_4)
6553
+
6554
+ assert_diagnoses(
6555
+ [:error, :unexpected_token, { :token => 'tLCURLY' }],
6556
+ %q{m [] {}},
6557
+ %q{ ^ location},
6558
+ SINCE_2_4)
6559
+
6560
+ assert_parses(
6561
+ s(:block,
6562
+ s(:send,
6563
+ s(:send, nil, :meth), :[]),
6564
+ s(:args), nil),
6565
+ %q{meth[] {}},
6566
+ %q{},
6567
+ SINCE_2_4
6568
+ )
6569
+
6570
+ assert_diagnoses_many(
6571
+ [
6572
+ [:warning, :ambiguous_literal],
6573
+ [:error, :unexpected_token, { :token => 'tLCURLY' }]
6574
+ ],
6575
+ %q{m /foo/ {}},
6576
+ SINCE_2_4)
6577
+
6578
+ assert_diagnoses_many(
6579
+ [
6580
+ [:warning, :ambiguous_literal],
6581
+ [:error, :unexpected_token, { :token => 'tLCURLY' }]
6582
+ ],
6583
+ %q{m /foo/x {}},
6584
+ SINCE_2_4)
6585
+ end
6024
6586
  end