parser 2.4.0.2 → 2.5.0.0

Sign up to get free protection for your applications and to get access to all the features.
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