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
@@ -274,12 +274,14 @@ rule
274
274
  cmd_brace_block: tLBRACE_ARG
275
275
  {
276
276
  @static_env.extend_dynamic
277
+ @context.push(:block)
277
278
  }
278
279
  opt_block_param compstmt tRCURLY
279
280
  {
280
281
  result = [ val[0], val[2], val[3], val[4] ]
281
282
 
282
283
  @static_env.unextend
284
+ @context.pop
283
285
  }
284
286
 
285
287
  command: operation command_args =tLOWEST
@@ -1122,10 +1124,11 @@ rule
1122
1124
  {
1123
1125
  @static_env.extend_static
1124
1126
  @lexer.push_cmdarg
1127
+ @context.push(:class)
1125
1128
  }
1126
1129
  bodystmt kEND
1127
1130
  {
1128
- if in_def?
1131
+ if @context.indirectly_in_def?
1129
1132
  diagnostic :error, :class_in_def, nil, val[0]
1130
1133
  end
1131
1134
 
@@ -1136,14 +1139,13 @@ rule
1136
1139
 
1137
1140
  @lexer.pop_cmdarg
1138
1141
  @static_env.unextend
1142
+ @context.pop
1139
1143
  }
1140
1144
  | kCLASS tLSHFT expr term
1141
1145
  {
1142
- result = @def_level
1143
- @def_level = 0
1144
-
1145
1146
  @static_env.extend_static
1146
1147
  @lexer.push_cmdarg
1148
+ @context.push(:sclass)
1147
1149
  }
1148
1150
  bodystmt kEND
1149
1151
  {
@@ -1152,8 +1154,7 @@ rule
1152
1154
 
1153
1155
  @lexer.pop_cmdarg
1154
1156
  @static_env.unextend
1155
-
1156
- @def_level = val[4]
1157
+ @context.pop
1157
1158
  }
1158
1159
  | kMODULE cpath
1159
1160
  {
@@ -1162,7 +1163,7 @@ rule
1162
1163
  }
1163
1164
  bodystmt kEND
1164
1165
  {
1165
- if in_def?
1166
+ if @context.indirectly_in_def?
1166
1167
  diagnostic :error, :module_in_def, nil, val[0]
1167
1168
  end
1168
1169
 
@@ -1174,9 +1175,9 @@ rule
1174
1175
  }
1175
1176
  | kDEF fname
1176
1177
  {
1177
- @def_level += 1
1178
1178
  @static_env.extend_static
1179
1179
  @lexer.push_cmdarg
1180
+ @context.push(:def)
1180
1181
  }
1181
1182
  f_arglist bodystmt kEND
1182
1183
  {
@@ -1185,7 +1186,7 @@ rule
1185
1186
 
1186
1187
  @lexer.pop_cmdarg
1187
1188
  @static_env.unextend
1188
- @def_level -= 1
1189
+ @context.pop
1189
1190
  }
1190
1191
  | kDEF singleton dot_or_colon
1191
1192
  {
@@ -1193,9 +1194,9 @@ rule
1193
1194
  }
1194
1195
  fname
1195
1196
  {
1196
- @def_level += 1
1197
1197
  @static_env.extend_static
1198
1198
  @lexer.push_cmdarg
1199
+ @context.push(:defs)
1199
1200
  }
1200
1201
  f_arglist bodystmt kEND
1201
1202
  {
@@ -1204,7 +1205,7 @@ rule
1204
1205
 
1205
1206
  @lexer.pop_cmdarg
1206
1207
  @static_env.unextend
1207
- @def_level -= 1
1208
+ @context.pop
1208
1209
  }
1209
1210
  | kBREAK
1210
1211
  {
@@ -1468,24 +1469,36 @@ rule
1468
1469
  result = @builder.args(nil, val[0], nil)
1469
1470
  }
1470
1471
 
1471
- lambda_body: tLAMBEG compstmt tRCURLY
1472
+ lambda_body: tLAMBEG
1473
+ {
1474
+ @context.push(:lambda)
1475
+ }
1476
+ compstmt tRCURLY
1472
1477
  {
1473
- result = [ val[0], val[1], val[2] ]
1478
+ result = [ val[0], val[2], val[3] ]
1479
+ @context.pop
1474
1480
  }
1475
- | kDO_LAMBDA compstmt kEND
1481
+ | kDO_LAMBDA
1476
1482
  {
1477
- result = [ val[0], val[1], val[2] ]
1483
+ @context.push(:lambda)
1484
+ }
1485
+ compstmt kEND
1486
+ {
1487
+ result = [ val[0], val[2], val[3] ]
1488
+ @context.pop
1478
1489
  }
1479
1490
 
1480
1491
  do_block: kDO_BLOCK
1481
1492
  {
1482
1493
  @static_env.extend_dynamic
1494
+ @context.push(:block)
1483
1495
  }
1484
1496
  opt_block_param compstmt kEND
1485
1497
  {
1486
1498
  result = [ val[0], val[2], val[3], val[4] ]
1487
1499
 
1488
1500
  @static_env.unextend
1501
+ @context.pop
1489
1502
  }
1490
1503
 
1491
1504
  block_call: command do_block
@@ -1559,22 +1572,26 @@ rule
1559
1572
  brace_block: tLCURLY
1560
1573
  {
1561
1574
  @static_env.extend_dynamic
1575
+ @context.push(:block)
1562
1576
  }
1563
1577
  opt_block_param compstmt tRCURLY
1564
1578
  {
1565
1579
  result = [ val[0], val[2], val[3], val[4] ]
1566
1580
 
1567
1581
  @static_env.unextend
1582
+ @context.pop
1568
1583
  }
1569
1584
  | kDO
1570
1585
  {
1571
1586
  @static_env.extend_dynamic
1587
+ @context.push(:block)
1572
1588
  }
1573
1589
  opt_block_param compstmt kEND
1574
1590
  {
1575
1591
  result = [ val[0], val[2], val[3], val[4] ]
1576
1592
 
1577
1593
  @static_env.unextend
1594
+ @context.pop
1578
1595
  }
1579
1596
 
1580
1597
  case_body: kWHEN args then compstmt cases
@@ -2170,8 +2187,6 @@ end
2170
2187
 
2171
2188
  require 'parser'
2172
2189
 
2173
- Parser.check_for_encoding_support
2174
-
2175
2190
  ---- inner
2176
2191
 
2177
2192
  def version
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Parser
2
4
  ##
3
5
  # Diagnostic messages (errors, warnings and notices) that can be generated.
@@ -26,6 +28,8 @@ module Parser
26
28
  :bare_backslash => 'bare backslash only allowed before newline',
27
29
  :unexpected => "unexpected `%{character}'",
28
30
  :embedded_document => 'embedded document meets end of file (and they embark on a romantic journey)',
31
+ :heredoc_id_has_newline => 'here document identifier across newlines, never match',
32
+ :heredoc_id_ends_with_nl => 'here document identifier ends with a newline',
29
33
 
30
34
  # Lexer warnings
31
35
  :invalid_escape_use => 'invalid character syntax; use ?%{escape}',
@@ -56,6 +60,7 @@ module Parser
56
60
  :masgn_as_condition => 'multiple assignment in conditional context',
57
61
  :block_given_to_yield => 'block given to yield',
58
62
  :invalid_regexp => '%{message}',
63
+ :invalid_return => 'Invalid return in class/module body',
59
64
 
60
65
  # Parser warnings
61
66
  :useless_else => 'else without rescue is useless',
@@ -66,5 +71,14 @@ module Parser
66
71
  # Rewriter diagnostics
67
72
  :invalid_action => 'cannot %{action}',
68
73
  :clobbered => 'clobbered by: %{action}',
74
+
75
+ # Rewriter diagnostics
76
+ :different_replacements => 'different replacements: %{replacement} vs %{other_replacement}',
77
+ :swallowed_insertions => 'this replacement:',
78
+ :swallowed_insertions_conflict => 'swallows some inner rewriting actions:',
79
+ :crossing_deletions => 'the deletion of:',
80
+ :crossing_deletions_conflict => 'is crossing:',
81
+ :crossing_insertions => 'the rewriting action on:',
82
+ :crossing_insertions_conflict => 'is crossing that on:',
69
83
  }.freeze
70
84
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Parser
2
4
  # Parser metadata
3
5
  module Meta
@@ -1,52 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Parser
2
4
 
3
5
  ##
4
- # {Parser::Rewriter} offers a basic API that makes it easy to rewrite
5
- # existing ASTs. It's built on top of {Parser::AST::Processor} and
6
- # {Parser::Source::Rewriter}.
7
- #
8
- # For example, assume you want to remove `do` tokens from a while statement.
9
- # You can do this as following:
10
- #
11
- # require 'parser/current'
12
- #
13
- # class RemoveDo < Parser::Rewriter
14
- # def on_while(node)
15
- # # Check if the statement starts with "do"
16
- # if node.location.begin.is?('do')
17
- # remove(node.location.begin)
18
- # end
19
- # end
20
- # end
21
- #
22
- # code = <<-EOF
23
- # while true do
24
- # puts 'hello'
25
- # end
26
- # EOF
27
- #
28
- # buffer = Parser::Source::Buffer.new('(example)')
29
- # buffer.source = code
30
- # parser = Parser::CurrentRuby.new
31
- # ast = parser.parse(buffer)
32
- # rewriter = RemoveDo.new
33
- #
34
- # # Rewrite the AST, returns a String with the new form.
35
- # puts rewriter.rewrite(buffer, ast)
36
- #
37
- # This would result in the following Ruby code:
38
- #
39
- # while true
40
- # puts 'hello'
41
- # end
42
- #
43
- # Keep in mind that {Parser::Rewriter} does not take care of indentation when
44
- # inserting/replacing code so you'll have to do this yourself.
45
- #
46
- # See also [a blog entry](http://whitequark.org/blog/2013/04/26/lets-play-with-ruby-code/)
47
- # describing rewriters in greater detail.
6
+ # {Parser::Rewriter} is deprecated. Use {Parser::TreeRewriter} instead.
7
+ # It has a backwards compatible API and uses {Parser::Source::TreeRewriter}
8
+ # instead of {Parser::Source::Rewriter}.
9
+ # Please check the documentation for {Parser::Source::Rewriter} for details.
48
10
  #
49
11
  # @api public
12
+ # @deprecated Use {Parser::TreeRewriter}
50
13
  #
51
14
  class Rewriter < Parser::AST::Processor
52
15
  ##
@@ -85,6 +48,16 @@ module Parser
85
48
  @source_rewriter.remove(range)
86
49
  end
87
50
 
51
+ ##
52
+ # Wraps the given source range with the given values.
53
+ #
54
+ # @param [Parser::Source::Range] range
55
+ # @param [String] content
56
+ #
57
+ def wrap(range, before, after)
58
+ @source_rewriter.wrap(range, before, after)
59
+ end
60
+
88
61
  ##
89
62
  # Inserts new code before the given source range.
90
63
  #
@@ -114,6 +87,19 @@ module Parser
114
87
  def replace(range, content)
115
88
  @source_rewriter.replace(range, content)
116
89
  end
90
+
91
+ DEPRECATION_WARNING = [
92
+ 'Parser::Rewriter is deprecated.',
93
+ 'Please update your code to use Parser::TreeRewriter instead'
94
+ ].join("\n").freeze
95
+
96
+ extend Deprecation
97
+
98
+ def initialize(*)
99
+ self.class.warn_of_deprecation
100
+ Source::Rewriter.warned_of_deprecation = true
101
+ super
102
+ end
117
103
  end
118
104
 
119
105
  end
@@ -142,7 +142,7 @@ rule
142
142
  }
143
143
  | klBEGIN tLCURLY compstmt tRCURLY
144
144
  {
145
- if in_def?
145
+ if @context.indirectly_in_def?
146
146
  diagnostic :error, :begin_in_method, nil, val[0]
147
147
  end
148
148
 
@@ -268,12 +268,14 @@ rule
268
268
  cmd_brace_block: tLBRACE_ARG
269
269
  {
270
270
  @static_env.extend_dynamic
271
+ @context.push(:block)
271
272
  }
272
273
  opt_block_var compstmt tRCURLY
273
274
  {
274
275
  result = [ val[0], val[2], val[3], val[4] ]
275
276
 
276
277
  @static_env.unextend
278
+ @context.pop
277
279
  }
278
280
 
279
281
  command: operation command_args =tLOWEST
@@ -1122,10 +1124,11 @@ rule
1122
1124
  | kCLASS cpath superclass
1123
1125
  {
1124
1126
  @static_env.extend_static
1127
+ @context.push(:class)
1125
1128
  }
1126
1129
  bodystmt kEND
1127
1130
  {
1128
- if in_def?
1131
+ if @context.indirectly_in_def?
1129
1132
  diagnostic :error, :class_in_def, nil, val[0]
1130
1133
  end
1131
1134
 
@@ -1135,13 +1138,12 @@ rule
1135
1138
  val[4], val[5])
1136
1139
 
1137
1140
  @static_env.unextend
1141
+ @context.pop
1138
1142
  }
1139
1143
  | kCLASS tLSHFT expr term
1140
1144
  {
1141
- result = @def_level
1142
- @def_level = 0
1143
-
1144
1145
  @static_env.extend_static
1146
+ @context.push(:sclass)
1145
1147
  }
1146
1148
  bodystmt kEND
1147
1149
  {
@@ -1149,8 +1151,7 @@ rule
1149
1151
  val[5], val[6])
1150
1152
 
1151
1153
  @static_env.unextend
1152
-
1153
- @def_level = val[4]
1154
+ @context.pop
1154
1155
  }
1155
1156
  | kMODULE cpath
1156
1157
  {
@@ -1158,7 +1159,7 @@ rule
1158
1159
  }
1159
1160
  bodystmt kEND
1160
1161
  {
1161
- if in_def?
1162
+ if @context.indirectly_in_def?
1162
1163
  diagnostic :error, :module_in_def, nil, val[0]
1163
1164
  end
1164
1165
 
@@ -1169,8 +1170,8 @@ rule
1169
1170
  }
1170
1171
  | kDEF fname
1171
1172
  {
1172
- @def_level += 1
1173
1173
  @static_env.extend_static
1174
+ @context.push(:def)
1174
1175
  }
1175
1176
  f_arglist bodystmt kEND
1176
1177
  {
@@ -1178,7 +1179,7 @@ rule
1178
1179
  val[3], val[4], val[5])
1179
1180
 
1180
1181
  @static_env.unextend
1181
- @def_level -= 1
1182
+ @context.pop
1182
1183
  }
1183
1184
  | kDEF singleton dot_or_colon
1184
1185
  {
@@ -1186,8 +1187,8 @@ rule
1186
1187
  }
1187
1188
  fname
1188
1189
  {
1189
- @def_level += 1
1190
1190
  @static_env.extend_static
1191
+ @context.push(:defs)
1191
1192
  }
1192
1193
  f_arglist bodystmt kEND
1193
1194
  {
@@ -1195,7 +1196,7 @@ rule
1195
1196
  val[4], val[6], val[7], val[8])
1196
1197
 
1197
1198
  @static_env.unextend
1198
- @def_level -= 1
1199
+ @context.pop
1199
1200
  }
1200
1201
  | kBREAK
1201
1202
  {
@@ -1330,12 +1331,14 @@ rule
1330
1331
  do_block: kDO_BLOCK
1331
1332
  {
1332
1333
  @static_env.extend_dynamic
1334
+ @context.push(:block)
1333
1335
  }
1334
1336
  opt_block_var compstmt kEND
1335
1337
  {
1336
1338
  result = [ val[0], val[2], val[3], val[4] ]
1337
1339
 
1338
1340
  @static_env.unextend
1341
+ @context.pop
1339
1342
  }
1340
1343
 
1341
1344
  block_call: command do_block
@@ -1393,22 +1396,26 @@ rule
1393
1396
  brace_block: tLCURLY
1394
1397
  {
1395
1398
  @static_env.extend_dynamic
1399
+ @context.push(:block)
1396
1400
  }
1397
1401
  opt_block_var compstmt tRCURLY
1398
1402
  {
1399
1403
  result = [ val[0], val[2], val[3], val[4] ]
1400
1404
 
1401
1405
  @static_env.unextend
1406
+ @context.pop
1402
1407
  }
1403
1408
  | kDO
1404
1409
  {
1405
1410
  @static_env.extend_dynamic
1411
+ @context.push(:block)
1406
1412
  }
1407
1413
  opt_block_var compstmt kEND
1408
1414
  {
1409
1415
  result = [ val[0], val[2], val[3], val[4] ]
1410
1416
 
1411
1417
  @static_env.unextend
1418
+ @context.pop
1412
1419
  }
1413
1420
 
1414
1421
  case_body: kWHEN when_args then compstmt cases
@@ -1923,5 +1930,5 @@ require 'parser'
1923
1930
  end
1924
1931
 
1925
1932
  def default_encoding
1926
- Encoding::BINARY if defined? Encoding
1933
+ Encoding::BINARY
1927
1934
  end