ripper_ruby_parser 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -1
  3. data/README.md +41 -9
  4. data/Rakefile +2 -0
  5. data/lib/ripper_ruby_parser.rb +2 -0
  6. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +23 -45
  7. data/lib/ripper_ruby_parser/parser.rb +11 -1
  8. data/lib/ripper_ruby_parser/sexp_handlers.rb +2 -6
  9. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +49 -35
  10. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +78 -39
  11. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +16 -15
  12. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +19 -15
  13. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +138 -30
  14. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +10 -6
  15. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +59 -14
  16. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +56 -32
  17. data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +20 -27
  18. data/lib/ripper_ruby_parser/sexp_processor.rb +40 -10
  19. data/lib/ripper_ruby_parser/syntax_error.rb +2 -0
  20. data/lib/ripper_ruby_parser/unescape.rb +32 -11
  21. data/lib/ripper_ruby_parser/version.rb +3 -1
  22. data/test/end_to_end/comments_test.rb +2 -0
  23. data/test/end_to_end/comparison_test.rb +2 -0
  24. data/test/end_to_end/lib_comparison_test.rb +2 -0
  25. data/test/end_to_end/line_numbering_test.rb +2 -0
  26. data/test/end_to_end/samples_comparison_test.rb +5 -29
  27. data/test/end_to_end/test_comparison_test.rb +2 -0
  28. data/test/pt_testcase/pt_test.rb +2 -0
  29. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +16 -2
  30. data/test/ripper_ruby_parser/parser_test.rb +17 -688
  31. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +459 -26
  32. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +152 -82
  33. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +91 -0
  34. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +331 -24
  35. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +88 -0
  36. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +58 -5
  37. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +392 -0
  38. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +174 -12
  39. data/test/ripper_ruby_parser/sexp_processor_test.rb +8 -18
  40. data/test/ripper_ruby_parser/version_test.rb +2 -0
  41. data/test/samples/comments.rb +13 -0
  42. data/test/samples/conditionals.rb +23 -0
  43. data/test/samples/loops.rb +36 -0
  44. data/test/samples/misc.rb +157 -5
  45. data/test/samples/number.rb +7 -0
  46. data/test/samples/strings.rb +39 -0
  47. data/test/test_helper.rb +22 -1
  48. metadata +18 -12
  49. data/lib/ripper_ruby_parser/sexp_handlers/arguments.rb +0 -29
  50. data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +0 -21
  51. data/lib/ripper_ruby_parser/sexp_handlers/hashes.rb +0 -48
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RipperRubyParser
2
4
  class SyntaxError < RuntimeError; end
3
5
  end
@@ -1,15 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RipperRubyParser
2
4
  # Implements string unescaping
3
5
  #
4
6
  # @api private
5
7
  module Unescape
6
- module_function
7
-
8
8
  ESCAPE_SEQUENCE_REGEXP =
9
9
  /\\(
10
10
  [0-7]{1,3} | # octal character
11
11
  x[0-9a-fA-F]{1,2} | # hex byte
12
- u[0-9a-fA-F]{4} | # unicode character
12
+ u[0-9a-fA-F]+ | # unicode character
13
+ u{[0-9a-fA-F]{4}} | # unicode character
13
14
  M-\\C-. | # meta-ctrl
14
15
  C-\\M-. | # ctrl-meta
15
16
  M-\\c. | # meta-ctrl (shorthand)
@@ -19,7 +20,7 @@ module RipperRubyParser
19
20
  M-. | # meta
20
21
  \n | # line continuation
21
22
  . # single-character
22
- )/x
23
+ )/x.freeze
23
24
 
24
25
  SINGLE_LETTER_ESCAPES = {
25
26
  'a' => "\a",
@@ -49,6 +50,7 @@ module RipperRubyParser
49
50
  string.gsub(/\\(
50
51
  ' | # single quote
51
52
  \\ | # backslash
53
+ [ ] | # space
52
54
  \n # newline
53
55
  )/x) do
54
56
  Regexp.last_match[1]
@@ -93,27 +95,46 @@ module RipperRubyParser
93
95
  end
94
96
  end
95
97
 
98
+ private
99
+
96
100
  def unescaped_value(bare)
97
101
  case bare
98
102
  when SINGLE_LETTER_ESCAPES_REGEXP
99
103
  SINGLE_LETTER_ESCAPES[bare]
100
104
  when /^x/
101
- bare[1..-1].to_i(16).chr
105
+ hex_to_char(bare[1..-1])
106
+ when /^u\{/
107
+ hex_to_unicode_char(bare[2..-2])
102
108
  when /^u/
103
- bare[1..-1].to_i(16).chr(Encoding::UTF_8)
109
+ hex_to_unicode_char(bare[1..4]) +
110
+ (extra_compatible ? '' : bare[5..-1])
104
111
  when /^(c|C-).$/
105
- (bare[-1].ord & 0b1001_1111).chr
112
+ control(bare[-1].ord).chr
106
113
  when /^M-.$/
107
- (bare[-1].ord | 0b1000_0000).chr
114
+ meta(bare[-1].ord).chr
108
115
  when /^(M-\\C-|C-\\M-|M-\\c|c\\M-).$/
109
- (bare[-1].ord & 0b1001_1111 | 0b1000_0000).chr
116
+ meta(control(bare[-1].ord)).chr
110
117
  when /^[0-7]+/
111
118
  bare.to_i(8).chr
112
- when "\n"
113
- bare
114
119
  else
115
120
  bare
116
121
  end
117
122
  end
123
+
124
+ def hex_to_unicode_char(str)
125
+ str.to_i(16).chr(Encoding::UTF_8)
126
+ end
127
+
128
+ def hex_to_char(str)
129
+ str.to_i(16).chr
130
+ end
131
+
132
+ def control(val)
133
+ val & 0b1001_1111
134
+ end
135
+
136
+ def meta(val)
137
+ val | 0b1000_0000
138
+ end
118
139
  end
119
140
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RipperRubyParser
2
- VERSION = '1.4.2'.freeze
4
+ VERSION = '1.5.0'
3
5
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
4
  require 'ruby_parser'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
4
  require 'ruby_parser'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
4
  require 'ruby_parser'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
4
  require 'ruby_parser'
3
5
 
@@ -1,37 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
4
  require 'ruby_parser'
3
5
 
4
6
  describe 'Using RipperRubyParser and RubyParser' do
5
- let :newparser do
6
- RipperRubyParser::Parser.new
7
- end
8
-
9
- let :oldparser do
10
- RubyParser.new
11
- end
12
-
13
7
  Dir.glob(File.expand_path('../samples/*.rb', File.dirname(__FILE__))).each do |file|
14
- describe "for #{file}" do
15
- let :program do
16
- File.read file
17
- end
18
-
19
- let :original do
20
- oldparser.parse program
21
- end
22
-
23
- let :imitation do
24
- newparser.parse program
25
- end
26
-
27
- it 'gives the same result' do
28
- formatted(imitation).must_equal formatted(original)
29
- end
30
-
31
- it 'gives the same result with comments' do
32
- formatted(to_comments(imitation)).
33
- must_equal formatted(to_comments(original))
34
- end
8
+ it "gives the same result for #{file}" do
9
+ program = File.read file
10
+ program.must_be_parsed_as_before
35
11
  end
36
12
  end
37
13
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
4
  require 'ruby_parser'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
4
  require 'pt_testcase'
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
4
 
3
5
  describe RipperRubyParser::CommentingRipperParser do
@@ -99,7 +101,7 @@ describe RipperRubyParser::CommentingRipperParser do
99
101
  result.must_equal s(:program,
100
102
  s(:stmts,
101
103
  s(:dyna_symbol,
102
- s(:xstring, s(:@tstring_content, 'foo', s(1, 2)))),
104
+ s(:xstring, s(:@tstring_content, 'foo', s(1, 2), ":'"))),
103
105
  s(:comment,
104
106
  '',
105
107
  s(:def,
@@ -114,7 +116,7 @@ describe RipperRubyParser::CommentingRipperParser do
114
116
  s(:stmts,
115
117
  s(:dyna_symbol,
116
118
  s(:xstring,
117
- s(:@tstring_content, 'foo', s(1, 2)),
119
+ s(:@tstring_content, 'foo', s(1, 2), ':"'),
118
120
  s(:string_embexpr,
119
121
  s(:stmts,
120
122
  s(:comment,
@@ -128,6 +130,18 @@ describe RipperRubyParser::CommentingRipperParser do
128
130
  nil,
129
131
  nil)))))))))
130
132
  end
133
+
134
+ it 'turns an embedded document into a comment node' do
135
+ result = parse_with_builder "=begin Hello\nthere\n=end\nclass Foo; end"
136
+ result.must_equal s(:program,
137
+ s(:stmts,
138
+ s(:comment,
139
+ "=begin Hello\nthere\n=end\n",
140
+ s(:class,
141
+ s(:const_ref, s(:@const, 'Foo', s(4, 6))),
142
+ nil,
143
+ s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil)))))
144
+ end
131
145
  end
132
146
 
133
147
  describe 'handling syntax errors' do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
2
4
 
3
5
  describe RipperRubyParser::Parser do
@@ -28,6 +30,11 @@ describe RipperRubyParser::Parser do
28
30
  end
29
31
 
30
32
  describe 'for a module declaration' do
33
+ it 'works with a simple module name' do
34
+ 'module Foo; end'.
35
+ must_be_parsed_as s(:module, :Foo)
36
+ end
37
+
31
38
  it 'works with a namespaced module name' do
32
39
  'module Foo::Bar; end'.
33
40
  must_be_parsed_as s(:module,
@@ -41,83 +48,6 @@ describe RipperRubyParser::Parser do
41
48
  end
42
49
  end
43
50
 
44
- describe 'for the return statement' do
45
- it 'works with no arguments' do
46
- 'return'.
47
- must_be_parsed_as s(:return)
48
- end
49
-
50
- it 'works with one argument' do
51
- 'return foo'.
52
- must_be_parsed_as s(:return,
53
- s(:call, nil, :foo))
54
- end
55
-
56
- it 'works with a splat argument' do
57
- 'return *foo'.
58
- must_be_parsed_as s(:return,
59
- s(:svalue,
60
- s(:splat,
61
- s(:call, nil, :foo))))
62
- end
63
-
64
- it 'works with multiple arguments' do
65
- 'return foo, bar'.
66
- must_be_parsed_as s(:return,
67
- s(:array,
68
- s(:call, nil, :foo),
69
- s(:call, nil, :bar)))
70
- end
71
-
72
- it 'works with a regular argument and a splat argument' do
73
- 'return foo, *bar'.
74
- must_be_parsed_as s(:return,
75
- s(:array,
76
- s(:call, nil, :foo),
77
- s(:splat,
78
- s(:call, nil, :bar))))
79
- end
80
-
81
- it 'works with a function call with parentheses' do
82
- 'return foo(bar)'.
83
- must_be_parsed_as s(:return,
84
- s(:call, nil, :foo,
85
- s(:call, nil, :bar)))
86
- end
87
-
88
- it 'works with a function call without parentheses' do
89
- 'return foo bar'.
90
- must_be_parsed_as s(:return,
91
- s(:call, nil, :foo,
92
- s(:call, nil, :bar)))
93
- end
94
- end
95
-
96
- describe 'for the for statement' do
97
- it 'works with do' do
98
- 'for foo in bar do; baz; end'.
99
- must_be_parsed_as s(:for,
100
- s(:call, nil, :bar),
101
- s(:lasgn, :foo),
102
- s(:call, nil, :baz))
103
- end
104
-
105
- it 'works without do' do
106
- 'for foo in bar; baz; end'.
107
- must_be_parsed_as s(:for,
108
- s(:call, nil, :bar),
109
- s(:lasgn, :foo),
110
- s(:call, nil, :baz))
111
- end
112
-
113
- it 'works with an empty body' do
114
- 'for foo in bar; end'.
115
- must_be_parsed_as s(:for,
116
- s(:call, nil, :bar),
117
- s(:lasgn, :foo))
118
- end
119
- end
120
-
121
51
  describe 'for a begin..end block' do
122
52
  it 'works with no statements' do
123
53
  'begin; end'.
@@ -137,57 +67,6 @@ describe RipperRubyParser::Parser do
137
67
  end
138
68
  end
139
69
 
140
- describe 'for the undef statement' do
141
- it 'works with a single bareword identifier' do
142
- 'undef foo'.
143
- must_be_parsed_as s(:undef, s(:lit, :foo))
144
- end
145
-
146
- it 'works with a single symbol' do
147
- 'undef :foo'.
148
- must_be_parsed_as s(:undef, s(:lit, :foo))
149
- end
150
-
151
- it 'works with multiple bareword identifiers' do
152
- 'undef foo, bar'.
153
- must_be_parsed_as s(:block,
154
- s(:undef, s(:lit, :foo)),
155
- s(:undef, s(:lit, :bar)))
156
- end
157
-
158
- it 'works with multiple bareword symbols' do
159
- 'undef :foo, :bar'.
160
- must_be_parsed_as s(:block,
161
- s(:undef, s(:lit, :foo)),
162
- s(:undef, s(:lit, :bar)))
163
- end
164
- end
165
-
166
- describe 'for the alias statement' do
167
- it 'works with regular barewords' do
168
- 'alias foo bar'.
169
- must_be_parsed_as s(:alias,
170
- s(:lit, :foo), s(:lit, :bar))
171
- end
172
-
173
- it 'works with symbols' do
174
- 'alias :foo :bar'.
175
- must_be_parsed_as s(:alias,
176
- s(:lit, :foo), s(:lit, :bar))
177
- end
178
-
179
- it 'works with operator barewords' do
180
- 'alias + -'.
181
- must_be_parsed_as s(:alias,
182
- s(:lit, :+), s(:lit, :-))
183
- end
184
-
185
- it 'works with global variables' do
186
- 'alias $foo $bar'.
187
- must_be_parsed_as s(:valias, :$foo, :$bar)
188
- end
189
- end
190
-
191
70
  describe 'for arguments' do
192
71
  it 'works for a simple case with splat' do
193
72
  'foo *bar'.
@@ -222,241 +101,6 @@ describe RipperRubyParser::Parser do
222
101
  end
223
102
  end
224
103
 
225
- describe 'for collection indexing' do
226
- it 'works in the simple case' do
227
- 'foo[bar]'.
228
- must_be_parsed_as s(:call,
229
- s(:call, nil, :foo),
230
- :[],
231
- s(:call, nil, :bar))
232
- end
233
-
234
- it 'works without any indexes' do
235
- 'foo[]'.must_be_parsed_as s(:call, s(:call, nil, :foo),
236
- :[])
237
- end
238
-
239
- it 'works with self[]' do
240
- 'self[foo]'.must_be_parsed_as s(:call, s(:self), :[],
241
- s(:call, nil, :foo))
242
- end
243
- end
244
-
245
- describe 'for method definitions' do
246
- it 'works with def with receiver' do
247
- 'def foo.bar; end'.
248
- must_be_parsed_as s(:defs,
249
- s(:call, nil, :foo),
250
- :bar,
251
- s(:args),
252
- s(:nil))
253
- end
254
-
255
- it 'works with def with receiver and multiple statements' do
256
- 'def foo.bar; baz; qux; end'.
257
- must_be_parsed_as s(:defs,
258
- s(:call, nil, :foo),
259
- :bar,
260
- s(:args),
261
- s(:call, nil, :baz),
262
- s(:call, nil, :qux))
263
- end
264
-
265
- it 'works with a method argument with a default value' do
266
- 'def foo bar=nil; end'.
267
- must_be_parsed_as s(:defn,
268
- :foo,
269
- s(:args, s(:lasgn, :bar, s(:nil))),
270
- s(:nil))
271
- end
272
-
273
- it 'works with several method arguments with default values' do
274
- 'def foo bar=1, baz=2; end'.
275
- must_be_parsed_as s(:defn,
276
- :foo,
277
- s(:args,
278
- s(:lasgn, :bar, s(:lit, 1)),
279
- s(:lasgn, :baz, s(:lit, 2))),
280
- s(:nil))
281
- end
282
-
283
- it 'works with parentheses around the parameter list' do
284
- 'def foo(bar); end'.
285
- must_be_parsed_as s(:defn, :foo, s(:args, :bar), s(:nil))
286
- end
287
-
288
- it 'works with a simple splat' do
289
- 'def foo *bar; end'.
290
- must_be_parsed_as s(:defn, :foo, s(:args, :"*bar"), s(:nil))
291
- end
292
-
293
- it 'works with a regular argument plus splat' do
294
- 'def foo bar, *baz; end'.
295
- must_be_parsed_as s(:defn, :foo, s(:args, :bar, :"*baz"), s(:nil))
296
- end
297
-
298
- it 'works with a nameless splat' do
299
- 'def foo *; end'.
300
- must_be_parsed_as s(:defn,
301
- :foo,
302
- s(:args, :"*"),
303
- s(:nil))
304
- end
305
-
306
- it 'works for a simple case with explicit block parameter' do
307
- 'def foo &bar; end'.
308
- must_be_parsed_as s(:defn,
309
- :foo,
310
- s(:args, :"&bar"),
311
- s(:nil))
312
- end
313
-
314
- it 'works with a regular argument plus explicit block parameter' do
315
- 'def foo bar, &baz; end'.
316
- must_be_parsed_as s(:defn,
317
- :foo,
318
- s(:args, :bar, :"&baz"),
319
- s(:nil))
320
- end
321
-
322
- it 'works with a default value plus explicit block parameter' do
323
- 'def foo bar=1, &baz; end'.
324
- must_be_parsed_as s(:defn,
325
- :foo,
326
- s(:args,
327
- s(:lasgn, :bar, s(:lit, 1)),
328
- :"&baz"),
329
- s(:nil))
330
- end
331
-
332
- it 'works with a default value plus mandatory argument' do
333
- 'def foo bar=1, baz; end'.
334
- must_be_parsed_as s(:defn,
335
- :foo,
336
- s(:args,
337
- s(:lasgn, :bar, s(:lit, 1)),
338
- :baz),
339
- s(:nil))
340
- end
341
-
342
- it 'works with a splat plus explicit block parameter' do
343
- 'def foo *bar, &baz; end'.
344
- must_be_parsed_as s(:defn,
345
- :foo,
346
- s(:args, :"*bar", :"&baz"),
347
- s(:nil))
348
- end
349
-
350
- it 'works with a default value plus splat' do
351
- 'def foo bar=1, *baz; end'.
352
- must_be_parsed_as s(:defn,
353
- :foo,
354
- s(:args,
355
- s(:lasgn, :bar, s(:lit, 1)),
356
- :"*baz"),
357
- s(:nil))
358
- end
359
-
360
- it 'works with a default value, splat, plus final mandatory arguments' do
361
- 'def foo bar=1, *baz, qux, quuz; end'.
362
- must_be_parsed_as s(:defn,
363
- :foo,
364
- s(:args,
365
- s(:lasgn, :bar, s(:lit, 1)),
366
- :"*baz", :qux, :quuz),
367
- s(:nil))
368
- end
369
-
370
- it 'works with a named argument with a default value' do
371
- 'def foo bar: 1; end'.
372
- must_be_parsed_as s(:defn,
373
- :foo,
374
- s(:args,
375
- s(:kwarg, :bar, s(:lit, 1))),
376
- s(:nil))
377
- end
378
-
379
- it 'works with a named argument with no default value' do
380
- 'def foo bar:; end'.
381
- must_be_parsed_as s(:defn,
382
- :foo,
383
- s(:args,
384
- s(:kwarg, :bar)),
385
- s(:nil))
386
- end
387
-
388
- it 'works with a double splat' do
389
- 'def foo **bar; end'.
390
- must_be_parsed_as s(:defn,
391
- :foo,
392
- s(:args, :'**bar'),
393
- s(:nil))
394
- end
395
-
396
- it 'works when the method name is an operator' do
397
- 'def +; end'.
398
- must_be_parsed_as s(:defn, :+, s(:args),
399
- s(:nil))
400
- end
401
- end
402
-
403
- describe 'for yield' do
404
- it 'works with no arguments and no parentheses' do
405
- 'yield'.
406
- must_be_parsed_as s(:yield)
407
- end
408
-
409
- it 'works with parentheses but no arguments' do
410
- 'yield()'.
411
- must_be_parsed_as s(:yield)
412
- end
413
-
414
- it 'works with one argument and no parentheses' do
415
- 'yield foo'.
416
- must_be_parsed_as s(:yield, s(:call, nil, :foo))
417
- end
418
-
419
- it 'works with one argument and parentheses' do
420
- 'yield(foo)'.
421
- must_be_parsed_as s(:yield, s(:call, nil, :foo))
422
- end
423
-
424
- it 'works with multiple arguments and no parentheses' do
425
- 'yield foo, bar'.
426
- must_be_parsed_as s(:yield,
427
- s(:call, nil, :foo),
428
- s(:call, nil, :bar))
429
- end
430
-
431
- it 'works with multiple arguments and parentheses' do
432
- 'yield(foo, bar)'.
433
- must_be_parsed_as s(:yield,
434
- s(:call, nil, :foo),
435
- s(:call, nil, :bar))
436
- end
437
-
438
- it 'works with splat' do
439
- 'yield foo, *bar'.
440
- must_be_parsed_as s(:yield,
441
- s(:call, nil, :foo),
442
- s(:splat, s(:call, nil, :bar)))
443
- end
444
-
445
- it 'works with a function call with parentheses' do
446
- 'yield foo(bar)'.
447
- must_be_parsed_as s(:yield,
448
- s(:call, nil, :foo,
449
- s(:call, nil, :bar)))
450
- end
451
-
452
- it 'works with a function call without parentheses' do
453
- 'yield foo bar'.
454
- must_be_parsed_as s(:yield,
455
- s(:call, nil, :foo,
456
- s(:call, nil, :bar)))
457
- end
458
- end
459
-
460
104
  describe 'for the __ENCODING__ keyword' do
461
105
  it 'evaluates to the equivalent of Encoding::UTF_8' do
462
106
  '__ENCODING__'.
@@ -494,6 +138,11 @@ describe RipperRubyParser::Parser do
494
138
  'END { foo }'.
495
139
  must_be_parsed_as s(:iter, s(:postexe), 0, s(:call, nil, :foo))
496
140
  end
141
+
142
+ it 'works with an empty block' do
143
+ 'END { }'.
144
+ must_be_parsed_as s(:iter, s(:postexe), 0)
145
+ end
497
146
  end
498
147
 
499
148
  describe 'for the BEGIN keyword' do
@@ -501,6 +150,11 @@ describe RipperRubyParser::Parser do
501
150
  'BEGIN { foo }'.
502
151
  must_be_parsed_as s(:iter, s(:preexe), s(:args), s(:call, nil, :foo))
503
152
  end
153
+
154
+ it 'works with an empty block' do
155
+ 'BEGIN { }'.
156
+ must_be_parsed_as s(:iter, s(:preexe), s(:args))
157
+ end
504
158
  end
505
159
 
506
160
  describe 'for constant lookups' do
@@ -553,307 +207,6 @@ describe RipperRubyParser::Parser do
553
207
  end
554
208
  end
555
209
 
556
- describe 'for single assignment' do
557
- it 'works when assigning to an instance variable' do
558
- '@foo = bar'.
559
- must_be_parsed_as s(:iasgn,
560
- :@foo,
561
- s(:call, nil, :bar))
562
- end
563
-
564
- it 'works when assigning to a constant' do
565
- 'FOO = bar'.
566
- must_be_parsed_as s(:cdecl,
567
- :FOO,
568
- s(:call, nil, :bar))
569
- end
570
-
571
- it 'works when assigning to a collection element' do
572
- 'foo[bar] = baz'.
573
- must_be_parsed_as s(:attrasgn,
574
- s(:call, nil, :foo),
575
- :[]=,
576
- s(:call, nil, :bar),
577
- s(:call, nil, :baz))
578
- end
579
-
580
- it 'works when assigning to an attribute' do
581
- 'foo.bar = baz'.
582
- must_be_parsed_as s(:attrasgn,
583
- s(:call, nil, :foo),
584
- :bar=,
585
- s(:call, nil, :baz))
586
- end
587
-
588
- it 'works when assigning to a class variable' do
589
- '@@foo = bar'.
590
- must_be_parsed_as s(:cvdecl,
591
- :@@foo,
592
- s(:call, nil, :bar))
593
- end
594
-
595
- it 'works when assigning to a class variable inside a method' do
596
- 'def foo; @@bar = baz; end'.
597
- must_be_parsed_as s(:defn,
598
- :foo, s(:args),
599
- s(:cvasgn, :@@bar, s(:call, nil, :baz)))
600
- end
601
-
602
- it 'works when assigning to a class variable inside a method with a receiver' do
603
- 'def self.foo; @@bar = baz; end'.
604
- must_be_parsed_as s(:defs,
605
- s(:self),
606
- :foo, s(:args),
607
- s(:cvasgn, :@@bar, s(:call, nil, :baz)))
608
- end
609
-
610
- it 'works when assigning to a global variable' do
611
- '$foo = bar'.
612
- must_be_parsed_as s(:gasgn,
613
- :$foo,
614
- s(:call, nil, :bar))
615
- end
616
- end
617
-
618
- describe 'for operator assignment' do
619
- it 'works with +=' do
620
- 'foo += bar'.
621
- must_be_parsed_as s(:lasgn,
622
- :foo,
623
- s(:call,
624
- s(:lvar, :foo),
625
- :+,
626
- s(:call, nil, :bar)))
627
- end
628
-
629
- it 'works with -=' do
630
- 'foo -= bar'.
631
- must_be_parsed_as s(:lasgn,
632
- :foo,
633
- s(:call,
634
- s(:lvar, :foo),
635
- :-,
636
- s(:call, nil, :bar)))
637
- end
638
-
639
- it 'works with ||=' do
640
- 'foo ||= bar'.
641
- must_be_parsed_as s(:op_asgn_or,
642
- s(:lvar, :foo),
643
- s(:lasgn, :foo,
644
- s(:call, nil, :bar)))
645
- end
646
-
647
- it 'works when assigning to an instance variable' do
648
- '@foo += bar'.
649
- must_be_parsed_as s(:iasgn,
650
- :@foo,
651
- s(:call,
652
- s(:ivar, :@foo),
653
- :+,
654
- s(:call, nil, :bar)))
655
- end
656
-
657
- it 'works when assigning to a collection element' do
658
- 'foo[bar] += baz'.
659
- must_be_parsed_as s(:op_asgn1,
660
- s(:call, nil, :foo),
661
- s(:arglist, s(:call, nil, :bar)),
662
- :+,
663
- s(:call, nil, :baz))
664
- end
665
-
666
- it 'works with ||= when assigning to a collection element' do
667
- 'foo[bar] ||= baz'.
668
- must_be_parsed_as s(:op_asgn1,
669
- s(:call, nil, :foo),
670
- s(:arglist, s(:call, nil, :bar)),
671
- :"||",
672
- s(:call, nil, :baz))
673
- end
674
-
675
- it 'works when assigning to an attribute' do
676
- 'foo.bar += baz'.
677
- must_be_parsed_as s(:op_asgn2,
678
- s(:call, nil, :foo),
679
- :bar=,
680
- :+,
681
- s(:call, nil, :baz))
682
- end
683
-
684
- it 'works with ||= when assigning to an attribute' do
685
- 'foo.bar ||= baz'.
686
- must_be_parsed_as s(:op_asgn2,
687
- s(:call, nil, :foo),
688
- :bar=,
689
- :"||",
690
- s(:call, nil, :baz))
691
- end
692
- end
693
-
694
- describe 'for multiple assignment' do
695
- it 'works the same number of items on each side' do
696
- 'foo, bar = baz, qux'.
697
- must_be_parsed_as s(:masgn,
698
- s(:array, s(:lasgn, :foo), s(:lasgn, :bar)),
699
- s(:array,
700
- s(:call, nil, :baz),
701
- s(:call, nil, :qux)))
702
- end
703
-
704
- it 'works with a single item on the right-hand side' do
705
- 'foo, bar = baz'.
706
- must_be_parsed_as s(:masgn,
707
- s(:array, s(:lasgn, :foo), s(:lasgn, :bar)),
708
- s(:to_ary,
709
- s(:call, nil, :baz)))
710
- end
711
-
712
- it 'works with left-hand splat' do
713
- 'foo, *bar = baz, qux'.
714
- must_be_parsed_as s(:masgn,
715
- s(:array, s(:lasgn, :foo), s(:splat, s(:lasgn, :bar))),
716
- s(:array,
717
- s(:call, nil, :baz),
718
- s(:call, nil, :qux)))
719
- end
720
-
721
- it 'works with parentheses around the left-hand side' do
722
- '(foo, bar) = baz'.
723
- must_be_parsed_as s(:masgn,
724
- s(:array, s(:lasgn, :foo), s(:lasgn, :bar)),
725
- s(:to_ary, s(:call, nil, :baz)))
726
- end
727
-
728
- it 'works with complex destructuring' do
729
- 'foo, (bar, baz) = qux'.
730
- must_be_parsed_as s(:masgn,
731
- s(:array,
732
- s(:lasgn, :foo),
733
- s(:masgn,
734
- s(:array, s(:lasgn, :bar), s(:lasgn, :baz)))),
735
- s(:to_ary, s(:call, nil, :qux)))
736
- end
737
-
738
- it 'works with complex destructuring of the value' do
739
- 'foo, (bar, baz) = [qux, [quz, quuz]]'.
740
- must_be_parsed_as s(:masgn,
741
- s(:array,
742
- s(:lasgn, :foo),
743
- s(:masgn, s(:array, s(:lasgn, :bar), s(:lasgn, :baz)))),
744
- s(:to_ary,
745
- s(:array,
746
- s(:call, nil, :qux),
747
- s(:array, s(:call, nil, :quz), s(:call, nil, :quuz)))))
748
- end
749
-
750
- it 'works with instance variables' do
751
- '@foo, @bar = baz'.
752
- must_be_parsed_as s(:masgn,
753
- s(:array, s(:iasgn, :@foo), s(:iasgn, :@bar)),
754
- s(:to_ary, s(:call, nil, :baz)))
755
- end
756
-
757
- it 'works with class variables' do
758
- '@@foo, @@bar = baz'.
759
- must_be_parsed_as s(:masgn,
760
- s(:array, s(:cvdecl, :@@foo), s(:cvdecl, :@@bar)),
761
- s(:to_ary, s(:call, nil, :baz)))
762
- end
763
-
764
- it 'works with attributes' do
765
- 'foo.bar, foo.baz = qux'.
766
- must_be_parsed_as s(:masgn,
767
- s(:array,
768
- s(:attrasgn, s(:call, nil, :foo), :bar=),
769
- s(:attrasgn, s(:call, nil, :foo), :baz=)),
770
- s(:to_ary, s(:call, nil, :qux)))
771
- end
772
-
773
- it 'works with collection elements' do
774
- 'foo[1], bar[2] = baz'.
775
- must_be_parsed_as s(:masgn,
776
- s(:array,
777
- s(:attrasgn,
778
- s(:call, nil, :foo), :[]=, s(:lit, 1)),
779
- s(:attrasgn,
780
- s(:call, nil, :bar), :[]=, s(:lit, 2))),
781
- s(:to_ary, s(:call, nil, :baz)))
782
- end
783
-
784
- it 'works with constants' do
785
- 'Foo, Bar = baz'.
786
- must_be_parsed_as s(:masgn,
787
- s(:array, s(:cdecl, :Foo), s(:cdecl, :Bar)),
788
- s(:to_ary, s(:call, nil, :baz)))
789
- end
790
-
791
- it 'works with instance variables and splat' do
792
- '@foo, *@bar = baz'.
793
- must_be_parsed_as s(:masgn,
794
- s(:array,
795
- s(:iasgn, :@foo),
796
- s(:splat, s(:iasgn, :@bar))),
797
- s(:to_ary,
798
- s(:call, nil, :baz)))
799
- end
800
- end
801
-
802
- describe 'for operators' do
803
- it 'handles :!=' do
804
- 'foo != bar'.
805
- must_be_parsed_as s(:call,
806
- s(:call, nil, :foo),
807
- :!=,
808
- s(:call, nil, :bar))
809
- end
810
-
811
- it 'handles :=~ with two non-literals' do
812
- 'foo =~ bar'.
813
- must_be_parsed_as s(:call,
814
- s(:call, nil, :foo),
815
- :=~,
816
- s(:call, nil, :bar))
817
- end
818
-
819
- it 'handles :=~ with literal regexp on the left hand side' do
820
- '/foo/ =~ bar'.
821
- must_be_parsed_as s(:match2,
822
- s(:lit, /foo/),
823
- s(:call, nil, :bar))
824
- end
825
-
826
- it 'handles :=~ with literal regexp on the right hand side' do
827
- 'foo =~ /bar/'.
828
- must_be_parsed_as s(:match3,
829
- s(:lit, /bar/),
830
- s(:call, nil, :foo))
831
- end
832
-
833
- it 'handles unary !' do
834
- '!foo'.
835
- must_be_parsed_as s(:call, s(:call, nil, :foo), :!)
836
- end
837
-
838
- it 'converts :not to :!' do
839
- 'not foo'.
840
- must_be_parsed_as s(:call, s(:call, nil, :foo), :!)
841
- end
842
-
843
- it 'handles unary ! with a number literal' do
844
- '!1'.
845
- must_be_parsed_as s(:call, s(:lit, 1), :!)
846
- end
847
-
848
- it 'handles the ternary operator' do
849
- 'foo ? bar : baz'.
850
- must_be_parsed_as s(:if,
851
- s(:call, nil, :foo),
852
- s(:call, nil, :bar),
853
- s(:call, nil, :baz))
854
- end
855
- end
856
-
857
210
  describe 'for expressions' do
858
211
  it 'handles assignment inside binary operator expressions' do
859
212
  'foo + (bar = baz)'.
@@ -938,15 +291,6 @@ describe RipperRubyParser::Parser do
938
291
  result[4].comments.must_equal "# bar\n"
939
292
  end
940
293
 
941
- it 'handles the use of symbols that are keywords' do
942
- result = parser.parse "# Foo\ndef bar\n:class\nend"
943
- result.must_equal s(:defn,
944
- :bar,
945
- s(:args),
946
- s(:lit, :class))
947
- result.comments.must_equal "# Foo\n"
948
- end
949
-
950
294
  it 'handles use of singleton class inside methods' do
951
295
  result = parser.parse "# Foo\ndef bar\nclass << self\nbaz\nend\nend"
952
296
  result.must_equal s(:defn,
@@ -1052,11 +396,6 @@ describe RipperRubyParser::Parser do
1052
396
  result.line.must_equal 1
1053
397
  end
1054
398
 
1055
- it 'works for a symbol literal' do
1056
- result = parser.parse ':foo'
1057
- result.line.must_equal 1
1058
- end
1059
-
1060
399
  it 'works for a class definition' do
1061
400
  result = parser.parse 'class Foo; end'
1062
401
  result.line.must_equal 1
@@ -1072,16 +411,6 @@ describe RipperRubyParser::Parser do
1072
411
  result.line.must_equal 1
1073
412
  end
1074
413
 
1075
- it 'works for assignment of the empty hash' do
1076
- result = parser.parse 'foo = {}'
1077
- result.line.must_equal 1
1078
- end
1079
-
1080
- it 'works for multiple assignment of empty hashes' do
1081
- result = parser.parse 'foo, bar = {}, {}'
1082
- result.line.must_equal 1
1083
- end
1084
-
1085
414
  it 'assigns line numbers to nested sexps without their own line numbers' do
1086
415
  result = parser.parse "foo(bar) do\nnext baz\nend\n"
1087
416
  result.must_equal s(:iter,