parser 2.7.1.5 → 2.7.2.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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/lib/parser/current.rb +1 -1
  3. data/lib/parser/meta.rb +2 -2
  4. data/lib/parser/ruby28.rb +8047 -0
  5. data/lib/parser/version.rb +1 -1
  6. data/parser.gemspec +1 -20
  7. metadata +7 -96
  8. data/.travis.yml +0 -41
  9. data/.yardopts +0 -21
  10. data/CHANGELOG.md +0 -1137
  11. data/CONTRIBUTING.md +0 -17
  12. data/Gemfile +0 -10
  13. data/LICENSE.txt +0 -25
  14. data/README.md +0 -309
  15. data/Rakefile +0 -167
  16. data/ci/run_rubocop_specs +0 -14
  17. data/doc/AST_FORMAT.md +0 -2284
  18. data/doc/CUSTOMIZATION.md +0 -37
  19. data/doc/INTERNALS.md +0 -21
  20. data/doc/css/.gitkeep +0 -0
  21. data/doc/css/common.css +0 -68
  22. data/lib/parser/lexer.rl +0 -2550
  23. data/lib/parser/macruby.y +0 -2208
  24. data/lib/parser/ruby18.y +0 -1936
  25. data/lib/parser/ruby19.y +0 -2185
  26. data/lib/parser/ruby20.y +0 -2363
  27. data/lib/parser/ruby21.y +0 -2364
  28. data/lib/parser/ruby22.y +0 -2371
  29. data/lib/parser/ruby23.y +0 -2377
  30. data/lib/parser/ruby24.y +0 -2415
  31. data/lib/parser/ruby25.y +0 -2412
  32. data/lib/parser/ruby26.y +0 -2420
  33. data/lib/parser/ruby27.y +0 -2949
  34. data/lib/parser/ruby30.y +0 -3048
  35. data/lib/parser/rubymotion.y +0 -2192
  36. data/test/bug_163/fixtures/input.rb +0 -5
  37. data/test/bug_163/fixtures/output.rb +0 -5
  38. data/test/bug_163/rewriter.rb +0 -20
  39. data/test/helper.rb +0 -103
  40. data/test/parse_helper.rb +0 -328
  41. data/test/racc_coverage_helper.rb +0 -133
  42. data/test/test_ast_processor.rb +0 -32
  43. data/test/test_base.rb +0 -31
  44. data/test/test_current.rb +0 -31
  45. data/test/test_diagnostic.rb +0 -95
  46. data/test/test_diagnostic_engine.rb +0 -59
  47. data/test/test_encoding.rb +0 -99
  48. data/test/test_lexer.rb +0 -3617
  49. data/test/test_lexer_stack_state.rb +0 -78
  50. data/test/test_meta.rb +0 -12
  51. data/test/test_parse_helper.rb +0 -83
  52. data/test/test_parser.rb +0 -9986
  53. data/test/test_runner_parse.rb +0 -56
  54. data/test/test_runner_rewrite.rb +0 -47
  55. data/test/test_source_buffer.rb +0 -165
  56. data/test/test_source_comment.rb +0 -36
  57. data/test/test_source_comment_associator.rb +0 -399
  58. data/test/test_source_map.rb +0 -14
  59. data/test/test_source_range.rb +0 -192
  60. data/test/test_source_rewriter.rb +0 -541
  61. data/test/test_source_rewriter_action.rb +0 -46
  62. data/test/test_source_tree_rewriter.rb +0 -361
  63. data/test/test_static_environment.rb +0 -45
  64. data/test/using_tree_rewriter/fixtures/input.rb +0 -3
  65. data/test/using_tree_rewriter/fixtures/output.rb +0 -3
  66. data/test/using_tree_rewriter/using_tree_rewriter.rb +0 -9
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
-
5
- class TestSourceRewriterAction < Minitest::Test
6
- def setup
7
- @buf = Parser::Source::Buffer.new('(rewriter_action)',
8
- source: 'foo bar baz')
9
- end
10
-
11
- def range(from, len)
12
- Parser::Source::Range.new(@buf, from, from + len)
13
- end
14
-
15
- def action(range, replacement)
16
- Parser::Source::Rewriter::Action.new(range, replacement)
17
- end
18
-
19
- def test_accessors
20
- action = action(range(1, 10), 'foo')
21
-
22
- assert action.frozen?
23
- assert_equal range(1, 10), action.range
24
- assert_equal 'foo', action.replacement
25
- end
26
-
27
- def test_to_s_replace
28
- action = action(range(3, 1), 'foo')
29
- assert_equal "replace 1 character(s) with \"foo\"", action.to_s
30
- end
31
-
32
- def test_to_s_insert
33
- action = action(range(3, 0), 'foo')
34
- assert_equal "insert \"foo\"", action.to_s
35
- end
36
-
37
- def test_to_s_remove
38
- action = action(range(3, 2), '')
39
- assert_equal 'remove 2 character(s)', action.to_s
40
- end
41
-
42
- def test_to_s_nop
43
- action = action(range(3, 0), '')
44
- assert_equal 'do nothing', action.to_s
45
- end
46
- end
@@ -1,361 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
-
5
- class TestSourceTreeRewriter < Minitest::Test
6
- module Setup
7
- def setup
8
- @buf = Parser::Source::Buffer.new('(rewriter)',
9
- source: 'puts(:hello, :world)')
10
-
11
- @hello = range(5, 6)
12
- @ll = range(8, 2)
13
- @comma_space = range(11,2)
14
- @world = range(13,6)
15
- @whole = range(0, @buf.source.length)
16
- end
17
-
18
- def range(from, len = nil)
19
- from, len = from.begin, from.end - from.begin unless len
20
- Parser::Source::Range.new(@buf, from, from + len)
21
- end
22
- end
23
-
24
- include Setup
25
-
26
- # Returns either:
27
- # - yield rewriter
28
- # - [diagnostic, ...] (Diagnostics)
29
- # - Parser::ClobberingError
30
- #
31
- def build(actions, **policy)
32
- diagnostics = []
33
- diags = -> { diagnostics.flatten.map(&:strip).join("\n") }
34
- rewriter = Parser::Source::TreeRewriter.new(@buf, **policy)
35
- rewriter.diagnostics.consumer = -> diag { diagnostics << diag.render }
36
- actions.each do |action, range, *args|
37
- rewriter.public_send(action, range, *args)
38
- end
39
- if diagnostics.empty?
40
- yield rewriter
41
- else
42
- diags.call
43
- end
44
- rescue ::Parser::ClobberingError => _e
45
- [::Parser::ClobberingError, diags.call]
46
- end
47
-
48
- # Returns either:
49
- # - String (Normal operation)
50
- # - [diagnostic, ...] (Diagnostics)
51
- # - Parser::ClobberingError
52
- #
53
- def apply(actions, **policy)
54
- build(actions, **policy) { |rewriter| rewriter.process }
55
- end
56
-
57
- # Expects ordered actions to be grouped together
58
- def check_actions(expected, grouped_actions, **policy)
59
- grouped_actions.permutation do |sequence|
60
- # [action, [action, action]] => [action, action, action]
61
- # except we can't use flatten because "action" are arrays themselves
62
- actions = sequence.flat_map { |group| group.first.is_a?(Array) ? group : [group] }
63
- assert_equal(expected, apply(actions, **policy))
64
- end
65
- end
66
-
67
- def assert_actions_result(expected, *actions, **rest)
68
- if expected == :raise
69
- diagnostic = rest.values.first
70
- check_actions([::Parser::ClobberingError, diagnostic], actions)
71
- elsif rest.empty?
72
- check_actions(expected, actions)
73
- else
74
- policy, diagnostic = rest.first
75
- check_actions(expected, actions, policy => :accept)
76
- check_actions(diagnostic, actions, policy => :warn)
77
- diagnostic.gsub!(/warning: /, 'error: ')
78
- check_actions([::Parser::ClobberingError, diagnostic], actions, policy => :raise)
79
- end
80
- end
81
-
82
- ### Simple cases
83
-
84
- def test_remove
85
- assert_actions_result 'puts(, :world)', [:remove, @hello]
86
- end
87
-
88
- def test_insert_before
89
- assert_actions_result 'puts(:hello, 42, :world)', [:insert_before, @world, '42, ']
90
- end
91
-
92
- def test_insert_after
93
- assert_actions_result 'puts(:hello, 42, :world)', [:insert_after, @hello, ', 42']
94
- end
95
-
96
- def test_wrap
97
- assert_actions_result 'puts([:hello], :world)', [:wrap, @hello, '[', ']']
98
- end
99
-
100
- def test_replace
101
- assert_actions_result 'puts(:hi, :world)', [:replace, @hello, ':hi']
102
- end
103
-
104
- #
105
- # All other cases, as per doc
106
- #
107
-
108
- def test_crossing_non_deletions
109
- check = [
110
- [:wrap, '(', ')'],
111
- [:remove],
112
- [:replace, 'xx'],
113
- ]
114
- check.combination(2) do |(action, *args), (action_b, *args_b)|
115
- next if action == :remove && action_b == :remove
116
- assert_actions_result :raise,
117
- [[action, @hello.join(@comma_space), *args],
118
- [action_b, @world.join(@comma_space), *args_b]],
119
- diagnostic: <<-DIAGNOSTIC.chomp
120
- (rewriter):1:12: error: the rewriting action on:
121
- (rewriter):1: puts(:hello, :world)
122
- (rewriter):1: ^~~~~~~~
123
- (rewriter):1:6: error: is crossing that on:
124
- (rewriter):1: puts(:hello, :world)
125
- (rewriter):1: ^~~~~~~~
126
- DIAGNOSTIC
127
- end
128
- end
129
-
130
-
131
- def test_crossing_deletions
132
- assert_actions_result 'puts()',
133
- [[:remove, @hello.join(@comma_space)],
134
- [:remove, @world.join(@comma_space)]],
135
- crossing_deletions: <<-DIAGNOSTIC.chomp
136
- (rewriter):1:12: warning: the deletion of:
137
- (rewriter):1: puts(:hello, :world)
138
- (rewriter):1: ^~~~~~~~
139
- (rewriter):1:6: warning: is crossing:
140
- (rewriter):1: puts(:hello, :world)
141
- (rewriter):1: ^~~~~~~~
142
- DIAGNOSTIC
143
- end
144
-
145
- def test_multiple_actions
146
- assert_actions_result 'puts({:hello => [:everybody]})',
147
- [:replace, @comma_space, ' => '],
148
- [:wrap, @hello.join(@world), '{', '}'],
149
- [:replace, @world, ':everybody'],
150
- [:wrap, @world, '[', ']']
151
- end
152
-
153
- def test_wraps_same_range
154
- assert_actions_result 'puts([(:hello)], :world)',
155
- [[:wrap, @hello, '(', ')'],
156
- [:wrap, @hello, '[', ']']]
157
- end
158
-
159
- def test_inserts_on_empty_ranges
160
- assert_actions_result 'puts({x}:hello[y], :world)',
161
- [:insert_before, @hello.begin, '{'],
162
- [:replace, @hello.begin, 'x'],
163
- [:insert_after, @hello.begin, '}'],
164
- [:insert_before, @hello.end, '['],
165
- [:replace, @hello.end, 'y'],
166
- [:insert_after, @hello.end, ']']
167
- end
168
-
169
- def test_replace_same_range
170
- assert_actions_result 'puts(:hey, :world)',
171
- [[:replace, @hello, ':hi'],
172
- [:replace, @hello, ':hey']],
173
- different_replacements: <<-DIAGNOSTIC.chomp
174
- (rewriter):1:6: warning: different replacements: :hey vs :hi
175
- (rewriter):1: puts(:hello, :world)
176
- (rewriter):1: ^~~~~~
177
- DIAGNOSTIC
178
- end
179
-
180
- def test_swallowed_insertions
181
- assert_actions_result 'puts(:hi)',
182
- [[:wrap, @hello.adjust(begin_pos: 1), '__', '__'],
183
- [:replace, @world.adjust(end_pos: -2), 'xx'],
184
- [:replace, @hello.join(@world), ':hi']],
185
- swallowed_insertions: <<-DIAGNOSTIC.chomp
186
- (rewriter):1:6: warning: this replacement:
187
- (rewriter):1: puts(:hello, :world)
188
- (rewriter):1: ^~~~~~~~~~~~~~
189
- (rewriter):1:7: warning: swallows some inner rewriting actions:
190
- (rewriter):1: puts(:hello, :world)
191
- (rewriter):1: ^~~~~ ~~~~
192
- DIAGNOSTIC
193
- end
194
-
195
- def test_out_of_range_ranges
196
- rewriter = Parser::Source::TreeRewriter.new(@buf)
197
- assert_raises(IndexError) { rewriter.insert_before(range(0, 100), 'hola') }
198
- end
199
-
200
- def test_empty
201
- rewriter = Parser::Source::TreeRewriter.new(@buf)
202
- assert_equal true, rewriter.empty?
203
-
204
- # This is a trivial wrap
205
- rewriter.wrap(range(2,3), '', '')
206
- assert_equal true, rewriter.empty?
207
-
208
- # This is a trivial deletion
209
- rewriter.remove(range(2,0))
210
- assert_equal true, rewriter.empty?
211
-
212
- rewriter.remove(range(2,3))
213
- assert_equal false, rewriter.empty?
214
- end
215
-
216
- # splits array into two groups, yield all such possible pairs of groups
217
- # each_split([1, 2, 3, 4]) yields [1, 2], [3, 4];
218
- # then [1, 3], [2, 4]
219
- # ...
220
- # and finally [3, 4], [1, 2]
221
- def each_split(array)
222
- n = array.size
223
- first_split_size = n.div(2)
224
- splitting = (0...n).to_set
225
- splitting.to_a.combination(first_split_size) do |indices|
226
- yield array.values_at(*indices),
227
- array.values_at(*(splitting - indices))
228
- end
229
- end
230
-
231
- # Checks that `actions+extra` give the same result when
232
- # made in order or from subgroups that are later merged.
233
- # The `extra` actions are always added at the end of the second group.
234
- #
235
- def check_all_merge_possibilities(actions, extra, **policy)
236
- expected = apply(actions + extra, **policy)
237
-
238
- each_split(actions) do |actions_1, actions_2|
239
- build(actions_1, **policy) do |rewriter_1|
240
- build(actions_2 + extra, **policy) do |rewriter_2|
241
- result = rewriter_1.merge(rewriter_2).process
242
- assert_equal(expected, result,
243
- "Group 1: #{actions_1.inspect}\n\n" +
244
- "Group 2: #{(actions_2 + extra).inspect}"
245
- )
246
- end
247
- end
248
- end
249
- end
250
-
251
- def test_merge
252
- check_all_merge_possibilities([
253
- [:wrap, @whole, '<', '>'],
254
- [:replace, @comma_space, ' => '],
255
- [:wrap, @hello, '!', '!'],
256
- # Following two wraps must have same value as they
257
- # will be applied in different orders...
258
- [:wrap, @hello.join(@world), '{', '}'],
259
- [:wrap, @hello.join(@world), '{', '}'],
260
- [:remove, @ll],
261
- [:replace, @world, ':everybody'],
262
- [:wrap, @world, '[', ']']
263
- ],
264
- [ # ... but this one is always going to be applied last (extra)
265
- [:wrap, @hello.join(@world), '@', '@'],
266
- ])
267
- end
268
-
269
- def representation_example
270
- Parser::Source::TreeRewriter.new(@buf)
271
- .wrap(range(1...10), '(', ')')
272
- .insert_after(range(2...6), '!')
273
- .replace(range(2...4), 'foo')
274
- .remove(range(5...6))
275
- end
276
-
277
- def test_nested_actions
278
- result = representation_example.as_nested_actions
279
-
280
- assert_equal( [ [:wrap, 1...10, '(', ')'],
281
- [:wrap, 2...6, '', '!'], # aka "insert_after"
282
- [:replace, 2...4, 'foo'],
283
- [:replace, 5...6, ''], # aka "removal"
284
- ],
285
- result.each {|arr| arr[1] = arr[1].to_range }
286
- )
287
- end
288
-
289
- def test_ordered_replacements
290
- result = representation_example.as_replacements
291
-
292
- assert_equal( [ [ 1...1, '('],
293
- [ 2...4, 'foo'],
294
- [ 5...6, ''],
295
- [ 6...6, '!'],
296
- [ 10...10, ')'],
297
- ],
298
- result.map {|r, s| [r.to_range, s]}
299
- )
300
- end
301
- end
302
-
303
- class TestSourceTreeRewriterImport < Minitest::Test
304
- include TestSourceTreeRewriter::Setup
305
- def setup
306
- super
307
- @buf2 = Parser::Source::Buffer.new('(rewriter 2)',
308
- source: ':hello')
309
-
310
- @rewriter = Parser::Source::TreeRewriter.new(@buf)
311
-
312
- @rewriter2 = Parser::Source::TreeRewriter.new(@buf2)
313
-
314
- @hello2 = range2(0, 6)
315
- @ll2 = range2(3, 2)
316
- end
317
-
318
- def range2(from, len)
319
- Parser::Source::Range.new(@buf2, from, from + len)
320
- end
321
-
322
- def test_import_with_offset
323
- @rewriter2.wrap(@hello2, '[', ']')
324
- @rewriter.wrap(@hello.join(@world), '{', '}')
325
- @rewriter.import!(@rewriter2, offset: @hello.begin_pos)
326
- assert_equal 'puts({[:hello], :world})', @rewriter.process
327
- end
328
-
329
- def test_import_with_offset_from_bigger_source
330
- @rewriter2.wrap(@ll2, '[', ']')
331
- @rewriter.wrap(@hello, '{', '}')
332
- @rewriter2.import!(@rewriter, offset: -@hello.begin_pos)
333
- assert_equal '{:he[ll]o}', @rewriter2.process
334
- end
335
-
336
- def test_import_with_offset_and_self
337
- @rewriter.wrap(@ll, '[', ']')
338
- @rewriter.import!(@rewriter, offset: +3)
339
- @rewriter.replace(range(8,1), '**')
340
- assert_equal 'puts(:he[**l]o[, ]:world)', @rewriter.process
341
- @rewriter.import!(@rewriter, offset: -6)
342
- assert_equal 'pu[**s]([:h]e[**l]o[, ]:world)', @rewriter.process
343
- end
344
-
345
- def test_import_with_invalid_offset
346
- @rewriter.wrap(@ll, '[', ']')
347
- m = @rewriter.dup.import!(@rewriter, offset: -@ll.begin_pos)
348
- assert_equal '[pu]ts(:he[ll]o, :world)', m.process
349
- off = @buf.source.size - @ll.end_pos
350
- m = @rewriter.dup.import!(@rewriter, offset: off)
351
- assert_equal 'puts(:he[ll]o, :worl[d)]', m.process
352
- assert_raises { @rewriter.import!(@rewriter, offset: -@ll.begin_pos - 1) }
353
- assert_raises { @rewriter.import!(@rewriter, offset: off + 1) }
354
- assert_equal 'puts(:he[ll]o, :world)', @rewriter.process # Test atomicity of import!
355
- end
356
-
357
- def test_empty_import
358
- assert_equal @rewriter, @rewriter.import!(@rewriter2)
359
- assert_equal @rewriter, @rewriter.import!(@rewriter, offset: 42)
360
- end
361
- end
@@ -1,45 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'helper'
4
-
5
- class TestStaticEnvironment < Minitest::Test
6
- def setup
7
- @env = Parser::StaticEnvironment.new
8
- end
9
-
10
- def test_declare
11
- refute @env.declared?(:foo)
12
-
13
- @env.declare :foo
14
-
15
- assert @env.declared?(:foo)
16
- end
17
-
18
- def test_extend_static
19
- @env.declare :foo
20
- @env.extend_static
21
- @env.declare :bar
22
-
23
- refute @env.declared?(:foo)
24
- assert @env.declared?(:bar)
25
- end
26
-
27
- def test_extend_dynamic
28
- @env.declare :foo
29
- @env.extend_dynamic
30
- @env.declare :bar
31
-
32
- assert @env.declared?(:foo)
33
- assert @env.declared?(:bar)
34
- end
35
-
36
- def test_unextend
37
- @env.declare :foo
38
- @env.extend_dynamic
39
- @env.declare :bar
40
- @env.unextend
41
-
42
- assert @env.declared?(:foo)
43
- refute @env.declared?(:bar)
44
- end
45
- end