parser 0.9.alpha
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.
- checksums.yaml +7 -0
- data/.autotest +50 -0
- data/.gemtest +0 -0
- data/History.txt +558 -0
- data/Manifest.txt +18 -0
- data/README.txt +87 -0
- data/Rakefile +192 -0
- data/bin/ruby_parse +96 -0
- data/bin/ruby_parse_extract_error +130 -0
- data/lib/gauntlet_rubyparser.rb +117 -0
- data/lib/ruby18_parser.rb +5706 -0
- data/lib/ruby18_parser.y +1846 -0
- data/lib/ruby19_parser.rb +6054 -0
- data/lib/ruby19_parser.y +2035 -0
- data/lib/ruby_lexer.rb +6789 -0
- data/lib/ruby_parser.rb +4 -0
- data/lib/ruby_parser_extras.rb +1148 -0
- data/test/test_ruby_lexer.rb +2028 -0
- data/test/test_ruby_parser.rb +1772 -0
- data/test/test_ruby_parser_extras.rb +228 -0
- metadata +163 -0
@@ -0,0 +1,1772 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# ENV['VERBOSE'] = "1"
|
5
|
+
|
6
|
+
require 'minitest/autorun'
|
7
|
+
require 'ruby_parser'
|
8
|
+
|
9
|
+
$: << File.expand_path('~/Work/p4/zss/src/sexp_processor/dev/lib')
|
10
|
+
|
11
|
+
require 'pt_testcase'
|
12
|
+
|
13
|
+
class Sexp
|
14
|
+
alias oldeq2 ==
|
15
|
+
def ==(obj) # :nodoc:
|
16
|
+
if obj.class == self.class then
|
17
|
+
super and
|
18
|
+
(self.line.nil? or obj.line.nil? or self.line == obj.line)
|
19
|
+
else
|
20
|
+
false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class RubyParserTestCase < ParseTreeTestCase
|
26
|
+
attr_accessor :result, :processor
|
27
|
+
|
28
|
+
make_my_diffs_pretty!
|
29
|
+
|
30
|
+
def self.previous key
|
31
|
+
"Ruby"
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.generate_test klass, node, data, input_name, output_name
|
35
|
+
return if node.to_s =~ /bmethod|dmethod/
|
36
|
+
return if Array === data['Ruby']
|
37
|
+
|
38
|
+
output_name = "ParseTree"
|
39
|
+
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def assert_parse rb, pt
|
44
|
+
self.result = processor.parse rb
|
45
|
+
assert_equal pt, result
|
46
|
+
end
|
47
|
+
|
48
|
+
def assert_syntax_error rb, emsg
|
49
|
+
e = nil
|
50
|
+
assert_silent do
|
51
|
+
e = assert_raises RubyParser::SyntaxError do
|
52
|
+
processor.parse rb
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
assert_equal emsg, e.message
|
57
|
+
end
|
58
|
+
|
59
|
+
def assert_parse_error rb, emsg
|
60
|
+
e = nil
|
61
|
+
assert_silent do
|
62
|
+
e = assert_raises Racc::ParseError do
|
63
|
+
processor.parse rb
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
assert_equal emsg, e.message
|
68
|
+
end
|
69
|
+
|
70
|
+
def assert_parse_line rb, pt, line
|
71
|
+
assert_parse rb, pt
|
72
|
+
assert_equal line, result.line, "call should have line number"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module TestRubyParserShared
|
77
|
+
def setup
|
78
|
+
super
|
79
|
+
# p :test => [self.class, __name__]
|
80
|
+
end
|
81
|
+
|
82
|
+
BLOCK_DUP_MSG = "Both block arg and actual block given."
|
83
|
+
|
84
|
+
def test_double_block_error_01
|
85
|
+
assert_syntax_error "a(1, &b) { }", BLOCK_DUP_MSG
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_double_block_error_02
|
89
|
+
assert_syntax_error "a(1, &b) do end", BLOCK_DUP_MSG
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_double_block_error_03
|
93
|
+
assert_syntax_error "a 1, &b do end", BLOCK_DUP_MSG
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_double_block_error_04
|
97
|
+
assert_syntax_error "m.a(1, &b) { }", BLOCK_DUP_MSG
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_double_block_error_05
|
101
|
+
assert_syntax_error "m.a(1, &b) do end", BLOCK_DUP_MSG
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_double_block_error_06
|
105
|
+
assert_syntax_error "m.a 1, &b do end", BLOCK_DUP_MSG
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_double_block_error_07
|
109
|
+
assert_syntax_error "m::a(1, &b) { }", BLOCK_DUP_MSG
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_double_block_error_08
|
113
|
+
assert_syntax_error "m::a(1, &b) do end", BLOCK_DUP_MSG
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_double_block_error_09
|
117
|
+
assert_syntax_error "m::a 1, &b do end", BLOCK_DUP_MSG
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_wtf_7
|
121
|
+
rb = "a.b (1) {c}"
|
122
|
+
pt = s(:iter,
|
123
|
+
s(:call, s(:call, nil, :a), :b, s(:lit, 1)),
|
124
|
+
s(:args),
|
125
|
+
s(:call, nil, :c))
|
126
|
+
|
127
|
+
assert_parse rb, pt
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_wtf_8
|
131
|
+
rb = "a::b (1) {c}"
|
132
|
+
pt = s(:iter,
|
133
|
+
s(:call, s(:call, nil, :a), :b, s(:lit, 1)),
|
134
|
+
s(:args),
|
135
|
+
s(:call, nil, :c))
|
136
|
+
|
137
|
+
assert_parse rb, pt
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_attrasgn_array_lhs
|
141
|
+
rb = '[1, 2, 3, 4][from .. to] = ["a", "b", "c"]'
|
142
|
+
pt = s(:attrasgn,
|
143
|
+
s(:array, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4)),
|
144
|
+
:[]=,
|
145
|
+
s(:dot2,
|
146
|
+
s(:call, nil, :from),
|
147
|
+
s(:call, nil, :to)),
|
148
|
+
s(:array, s(:str, "a"), s(:str, "b"), s(:str, "c")))
|
149
|
+
|
150
|
+
assert_parse rb, pt
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_block_append
|
154
|
+
head = s(:args)
|
155
|
+
tail = s(:zsuper)
|
156
|
+
expected = s(:block, s(:args), s(:zsuper))
|
157
|
+
assert_equal expected, processor.block_append(head, tail)
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_block_append_begin_begin
|
161
|
+
head = s(:begin, s(:args))
|
162
|
+
tail = s(:begin, s(:args))
|
163
|
+
expected = s(:block, s(:args), s(:begin, s(:args)))
|
164
|
+
assert_equal expected, processor.block_append(head, tail)
|
165
|
+
end
|
166
|
+
|
167
|
+
def test_block_append_block
|
168
|
+
head = s(:block, s(:args))
|
169
|
+
tail = s(:zsuper)
|
170
|
+
expected = s(:block, s(:args), s(:zsuper))
|
171
|
+
assert_equal expected, processor.block_append(head, tail)
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_block_append_nil_head
|
175
|
+
head = nil
|
176
|
+
tail = s(:zsuper)
|
177
|
+
expected = s(:zsuper)
|
178
|
+
assert_equal expected, processor.block_append(head, tail)
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_block_append_nil_tail
|
182
|
+
head = s(:args)
|
183
|
+
tail = nil
|
184
|
+
expected = s(:args)
|
185
|
+
assert_equal expected, processor.block_append(head, tail)
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_block_append_tail_block
|
189
|
+
head = s(:call, nil, :f1)
|
190
|
+
tail = s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y)))
|
191
|
+
expected = s(:block,
|
192
|
+
s(:call, nil, :f1),
|
193
|
+
s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y))))
|
194
|
+
assert_equal expected, processor.block_append(head, tail)
|
195
|
+
end
|
196
|
+
|
197
|
+
def test_call_array_arg
|
198
|
+
rb = "1 == [:b, :c]"
|
199
|
+
pt = s(:call, s(:lit, 1), :==, s(:array, s(:lit, :b), s(:lit, :c)))
|
200
|
+
|
201
|
+
assert_parse rb, pt
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_call_env
|
205
|
+
processor.env[:a] = :lvar
|
206
|
+
rb = "a.happy"
|
207
|
+
pt = s(:call, s(:lvar, :a), :happy)
|
208
|
+
|
209
|
+
assert_parse rb, pt
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_dasgn_icky2
|
213
|
+
rb = "a do\n v = nil\n begin\n yield\n rescue Exception => v\n break\n end\nend"
|
214
|
+
pt = s(:iter,
|
215
|
+
s(:call, nil, :a),
|
216
|
+
s(:args),
|
217
|
+
s(:block,
|
218
|
+
s(:lasgn, :v, s(:nil)),
|
219
|
+
s(:rescue,
|
220
|
+
s(:yield),
|
221
|
+
s(:resbody,
|
222
|
+
s(:array, s(:const, :Exception), s(:lasgn, :v, s(:gvar, :$!))),
|
223
|
+
s(:break)))))
|
224
|
+
|
225
|
+
assert_parse rb, pt
|
226
|
+
end
|
227
|
+
|
228
|
+
def test_class_comments
|
229
|
+
rb = "# blah 1\n# blah 2\n\nclass X\n # blah 3\n def blah\n # blah 4\n end\nend"
|
230
|
+
pt = s(:class, :X, nil,
|
231
|
+
s(:defn, :blah, s(:args), s(:nil)))
|
232
|
+
|
233
|
+
assert_parse rb, pt
|
234
|
+
|
235
|
+
assert_equal "# blah 1\n# blah 2\n", result.comments
|
236
|
+
assert_equal "# blah 3\n", result.defn.comments
|
237
|
+
end
|
238
|
+
|
239
|
+
def test_module_comments
|
240
|
+
rb = "# blah 1\n \n # blah 2\n\nmodule X\n # blah 3\n def blah\n # blah 4\n end\nend"
|
241
|
+
pt = s(:module, :X,
|
242
|
+
s(:defn, :blah, s(:args), s(:nil)))
|
243
|
+
|
244
|
+
assert_parse rb, pt
|
245
|
+
assert_equal "# blah 1\n# blah 2\n", result.comments
|
246
|
+
assert_equal "# blah 3\n", result.defn.comments
|
247
|
+
end
|
248
|
+
|
249
|
+
def test_defn_comments
|
250
|
+
rb = "# blah 1\n# blah 2\n\ndef blah\nend"
|
251
|
+
pt = s(:defn, :blah, s(:args), s(:nil))
|
252
|
+
|
253
|
+
assert_parse rb, pt
|
254
|
+
assert_equal "# blah 1\n# blah 2\n", result.comments
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_defs_comments
|
258
|
+
rb = "# blah 1\n# blah 2\n\ndef self.blah\nend"
|
259
|
+
pt = s(:defs, s(:self), :blah, s(:args))
|
260
|
+
|
261
|
+
assert_parse rb, pt
|
262
|
+
assert_equal "# blah 1\n# blah 2\n", result.comments
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_do_bug # TODO: rename
|
266
|
+
rb = "a 1\na.b do |c|\n # do nothing\nend"
|
267
|
+
pt = s(:block,
|
268
|
+
s(:call, nil, :a, s(:lit, 1)),
|
269
|
+
s(:iter,
|
270
|
+
s(:call, s(:call, nil, :a), :b),
|
271
|
+
s(:args, :c)))
|
272
|
+
|
273
|
+
assert_parse rb, pt
|
274
|
+
end
|
275
|
+
|
276
|
+
def test_bug_comment_eq_begin
|
277
|
+
rb = "\n\n#\n=begin\nblah\n=end\n\n"
|
278
|
+
pt = nil
|
279
|
+
exp = rb.strip + "\n"
|
280
|
+
|
281
|
+
assert_parse rb, pt
|
282
|
+
assert_equal exp, processor.lexer.comments
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_bug_call_arglist_parens
|
286
|
+
rb = 'g ( 1), 2'
|
287
|
+
pt = s(:call, nil, :g, s(:lit, 1), s(:lit, 2))
|
288
|
+
|
289
|
+
assert_parse rb, pt
|
290
|
+
|
291
|
+
rb = <<-CODE
|
292
|
+
def f
|
293
|
+
g ( 1), 2
|
294
|
+
end
|
295
|
+
CODE
|
296
|
+
|
297
|
+
pt = s(:defn, :f, s(:args),
|
298
|
+
s(:call, nil, :g, s(:lit, 1), s(:lit, 2)))
|
299
|
+
|
300
|
+
assert_parse rb, pt
|
301
|
+
|
302
|
+
rb = <<-CODE
|
303
|
+
def f()
|
304
|
+
g (1), 2
|
305
|
+
end
|
306
|
+
CODE
|
307
|
+
|
308
|
+
assert_parse rb, pt
|
309
|
+
end
|
310
|
+
|
311
|
+
def test_dstr_evstr
|
312
|
+
rb = "\"#\{'a'}#\{b}\""
|
313
|
+
pt = s(:dstr, "a", s(:evstr, s(:call, nil, :b)))
|
314
|
+
|
315
|
+
assert_parse rb, pt
|
316
|
+
end
|
317
|
+
|
318
|
+
def test_dstr_str
|
319
|
+
rb = "\"#\{'a'} b\""
|
320
|
+
pt = s(:str, "a b")
|
321
|
+
|
322
|
+
assert_parse rb, pt
|
323
|
+
end
|
324
|
+
|
325
|
+
def test_empty
|
326
|
+
rb = ""
|
327
|
+
pt = nil
|
328
|
+
|
329
|
+
assert_parse rb, pt
|
330
|
+
end
|
331
|
+
|
332
|
+
def test_evstr_evstr
|
333
|
+
rb = "\"#\{a}#\{b}\""
|
334
|
+
pt = s(:dstr, "", s(:evstr, s(:call, nil, :a)), s(:evstr, s(:call, nil, :b)))
|
335
|
+
|
336
|
+
assert_parse rb, pt
|
337
|
+
end
|
338
|
+
|
339
|
+
def test_evstr_str
|
340
|
+
rb = "\"#\{a} b\""
|
341
|
+
pt = s(:dstr, "", s(:evstr, s(:call, nil, :a)), s(:str, " b"))
|
342
|
+
|
343
|
+
assert_parse rb, pt
|
344
|
+
end
|
345
|
+
|
346
|
+
def test_lasgn_env
|
347
|
+
rb = 'a = 42'
|
348
|
+
pt = s(:lasgn, :a, s(:lit, 42))
|
349
|
+
expected_env = { :a => :lvar }
|
350
|
+
|
351
|
+
assert_parse rb, pt
|
352
|
+
assert_equal expected_env, processor.env.all
|
353
|
+
end
|
354
|
+
|
355
|
+
def test_list_append
|
356
|
+
a = s(:lit, 1)
|
357
|
+
b = s(:lit, 2)
|
358
|
+
c = s(:lit, 3)
|
359
|
+
|
360
|
+
result = processor.list_append(s(:array, b.dup), c.dup)
|
361
|
+
|
362
|
+
assert_equal s(:array, b, c), result
|
363
|
+
|
364
|
+
result = processor.list_append(b.dup, c.dup)
|
365
|
+
|
366
|
+
assert_equal s(:array, b, c), result
|
367
|
+
|
368
|
+
result = processor.list_append(result, a.dup)
|
369
|
+
|
370
|
+
assert_equal s(:array, b, c, a), result
|
371
|
+
|
372
|
+
lhs, rhs = s(:array, s(:lit, :iter)), s(:when, s(:const, :BRANCHING), nil)
|
373
|
+
expected = s(:array, s(:lit, :iter), s(:when, s(:const, :BRANCHING), nil))
|
374
|
+
|
375
|
+
assert_equal expected, processor.list_append(lhs, rhs)
|
376
|
+
end
|
377
|
+
|
378
|
+
def test_list_prepend
|
379
|
+
a = s(:lit, 1)
|
380
|
+
b = s(:lit, 2)
|
381
|
+
c = s(:lit, 3)
|
382
|
+
|
383
|
+
result = processor.list_prepend(b.dup, s(:array, c.dup))
|
384
|
+
|
385
|
+
assert_equal s(:array, b, c), result
|
386
|
+
|
387
|
+
result = processor.list_prepend(b.dup, c.dup)
|
388
|
+
|
389
|
+
assert_equal s(:array, b, c), result
|
390
|
+
|
391
|
+
result = processor.list_prepend(a.dup, result)
|
392
|
+
|
393
|
+
assert_equal s(:array, a, b, c), result
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_literal_concat_dstr_dstr
|
397
|
+
lhs = s(:dstr, "Failed to download spec ",
|
398
|
+
s(:evstr, s(:call, nil, :spec_name)),
|
399
|
+
s(:str, " from "),
|
400
|
+
s(:evstr, s(:call, nil, :source_uri)),
|
401
|
+
s(:str, ":\n"))
|
402
|
+
rhs = s(:dstr, "\t",
|
403
|
+
s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
|
404
|
+
expected = s(:dstr, "Failed to download spec ",
|
405
|
+
s(:evstr, s(:call, nil, :spec_name)),
|
406
|
+
s(:str, " from "),
|
407
|
+
s(:evstr, s(:call, nil, :source_uri)),
|
408
|
+
s(:str, ":\n"),
|
409
|
+
s(:str, "\t"),
|
410
|
+
s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
|
411
|
+
|
412
|
+
assert_equal expected, processor.literal_concat(lhs, rhs)
|
413
|
+
end
|
414
|
+
|
415
|
+
def test_literal_concat_dstr_evstr
|
416
|
+
lhs, rhs = s(:dstr, "a"), s(:evstr, s(:call, nil, :b))
|
417
|
+
expected = s(:dstr, "a", s(:evstr, s(:call, nil, :b)))
|
418
|
+
|
419
|
+
assert_equal expected, processor.literal_concat(lhs, rhs)
|
420
|
+
end
|
421
|
+
|
422
|
+
def test_literal_concat_evstr_evstr
|
423
|
+
lhs, rhs = s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2))
|
424
|
+
expected = s(:dstr, "", s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2)))
|
425
|
+
|
426
|
+
assert_equal expected, processor.literal_concat(lhs, rhs)
|
427
|
+
end
|
428
|
+
|
429
|
+
def test_literal_concat_str_evstr
|
430
|
+
lhs, rhs = s(:str, ""), s(:evstr, s(:str, "blah"))
|
431
|
+
|
432
|
+
assert_equal s(:str, "blah"), processor.literal_concat(lhs, rhs)
|
433
|
+
end
|
434
|
+
|
435
|
+
def test_logop_12
|
436
|
+
lhs = s(:lit, 1)
|
437
|
+
rhs = s(:lit, 2)
|
438
|
+
exp = s(:and, s(:lit, 1), s(:lit, 2))
|
439
|
+
|
440
|
+
assert_equal exp, processor.logop(:and, lhs, rhs)
|
441
|
+
end
|
442
|
+
|
443
|
+
def test_logop_1234_5
|
444
|
+
lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:and, s(:lit, 3), s(:lit, 4))))
|
445
|
+
rhs = s(:lit, 5)
|
446
|
+
exp = s(:and,
|
447
|
+
s(:lit, 1),
|
448
|
+
s(:and,
|
449
|
+
s(:lit, 2),
|
450
|
+
s(:and,
|
451
|
+
s(:lit, 3),
|
452
|
+
s(:and,
|
453
|
+
s(:lit, 4),
|
454
|
+
s(:lit, 5)))))
|
455
|
+
|
456
|
+
assert_equal exp, processor.logop(:and, lhs, rhs)
|
457
|
+
end
|
458
|
+
|
459
|
+
def test_logop_123_4
|
460
|
+
lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
|
461
|
+
rhs = s(:lit, 4)
|
462
|
+
exp = s(:and,
|
463
|
+
s(:lit, 1),
|
464
|
+
s(:and,
|
465
|
+
s(:lit, 2),
|
466
|
+
s(:and,
|
467
|
+
s(:lit, 3),
|
468
|
+
s(:lit, 4))))
|
469
|
+
|
470
|
+
assert_equal exp, processor.logop(:and, lhs, rhs)
|
471
|
+
end
|
472
|
+
|
473
|
+
def test_logop_12_3
|
474
|
+
lhs = s(:and, s(:lit, 1), s(:lit, 2))
|
475
|
+
rhs = s(:lit, 3)
|
476
|
+
exp = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
|
477
|
+
|
478
|
+
assert_equal exp, processor.logop(:and, lhs, rhs)
|
479
|
+
end
|
480
|
+
|
481
|
+
def test_logop_nested_mix
|
482
|
+
lhs = s(:or, s(:call, nil, :a), s(:call, nil, :b))
|
483
|
+
rhs = s(:and, s(:call, nil, :c), s(:call, nil, :d))
|
484
|
+
exp = s(:or,
|
485
|
+
s(:or, s(:call, nil, :a), s(:call, nil, :b)),
|
486
|
+
s(:and, s(:call, nil, :c), s(:call, nil, :d)))
|
487
|
+
|
488
|
+
lhs.paren = true
|
489
|
+
rhs.paren = true
|
490
|
+
|
491
|
+
assert_equal exp, processor.logop(:or, lhs, rhs)
|
492
|
+
end
|
493
|
+
|
494
|
+
def test_str_evstr
|
495
|
+
rb = "\"a #\{b}\""
|
496
|
+
pt = s(:dstr, "a ", s(:evstr, s(:call, nil, :b)))
|
497
|
+
|
498
|
+
assert_parse rb, pt
|
499
|
+
end
|
500
|
+
|
501
|
+
def test_dsym_to_sym
|
502
|
+
pt = s(:alias, s(:lit, :<<), s(:lit, :>>))
|
503
|
+
|
504
|
+
rb = 'alias :<< :>>'
|
505
|
+
assert_parse rb, pt
|
506
|
+
|
507
|
+
rb = 'alias :"<<" :">>"'
|
508
|
+
assert_parse rb, pt
|
509
|
+
end
|
510
|
+
|
511
|
+
def test_regexp
|
512
|
+
regexps = {
|
513
|
+
"/wtf/" => /wtf/,
|
514
|
+
"/wtf/n" => /wtf/n,
|
515
|
+
"/wtf/m" => /wtf/m,
|
516
|
+
"/wtf/nm" => /wtf/nm,
|
517
|
+
"/wtf/nmnmnmnm" => /wtf/nm,
|
518
|
+
}
|
519
|
+
|
520
|
+
regexps.each do |rb, lit|
|
521
|
+
assert_parse rb, s(:lit, lit)
|
522
|
+
end
|
523
|
+
|
524
|
+
# TODO: add more including interpolation etc
|
525
|
+
end
|
526
|
+
|
527
|
+
def test_str_pct_Q_nested
|
528
|
+
rb = "%Q[before [#\{nest}] after]"
|
529
|
+
pt = s(:dstr, "before [", s(:evstr, s(:call, nil, :nest)), s(:str, "] after"))
|
530
|
+
|
531
|
+
assert_parse rb, pt
|
532
|
+
end
|
533
|
+
|
534
|
+
def test_str_pct_nested_nested
|
535
|
+
rb = "%{ { #\{ \"#\{1}\" } } }"
|
536
|
+
assert_equal " { 1 } ", eval(rb)
|
537
|
+
pt = s(:dstr, " { ", s(:evstr, s(:lit, 1)), s(:str, " } "))
|
538
|
+
|
539
|
+
assert_parse rb, pt
|
540
|
+
end
|
541
|
+
|
542
|
+
def test_str_str
|
543
|
+
rb = "\"a #\{'b'}\""
|
544
|
+
pt = s(:str, "a b")
|
545
|
+
|
546
|
+
assert_parse rb, pt
|
547
|
+
end
|
548
|
+
|
549
|
+
def test_str_str_str
|
550
|
+
rb = "\"a #\{'b'} c\""
|
551
|
+
pt = s(:str, "a b c")
|
552
|
+
|
553
|
+
assert_parse rb, pt
|
554
|
+
end
|
555
|
+
|
556
|
+
STARTING_LINE = {
|
557
|
+
"case_no_expr" => 2, # TODO this should be 1
|
558
|
+
"structure_unused_literal_wwtt" => 3, # yes, 3... odd test
|
559
|
+
}
|
560
|
+
|
561
|
+
def after_process_hook klass, node, data, input_name, output_name
|
562
|
+
expected = STARTING_LINE[node] || 1
|
563
|
+
assert_equal expected, @result.line, "should have proper line number"
|
564
|
+
end
|
565
|
+
|
566
|
+
def test_parse_line_block
|
567
|
+
rb = "a = 42\np a"
|
568
|
+
pt = s(:block,
|
569
|
+
s(:lasgn, :a, s(:lit, 42)),
|
570
|
+
s(:call, nil, :p, s(:lvar, :a)))
|
571
|
+
|
572
|
+
assert_parse_line rb, pt, 1
|
573
|
+
assert_equal 1, result.lasgn.line, "lasgn should have line number"
|
574
|
+
assert_equal 2, result.call.line, "call should have line number"
|
575
|
+
|
576
|
+
expected = "(string)"
|
577
|
+
assert_equal expected, result.file
|
578
|
+
assert_equal expected, result.lasgn.file
|
579
|
+
assert_equal expected, result.call.file
|
580
|
+
|
581
|
+
assert_same result.file, result.lasgn.file
|
582
|
+
assert_same result.file, result.call.file
|
583
|
+
end
|
584
|
+
|
585
|
+
def test_parse_line_call_no_args
|
586
|
+
rb = "f do |x, y|\n x + y\nend"
|
587
|
+
|
588
|
+
pt = s(:iter,
|
589
|
+
s(:call, nil, :f),
|
590
|
+
s(:args, :x, :y),
|
591
|
+
s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
|
592
|
+
|
593
|
+
assert_parse_line rb, pt, 1
|
594
|
+
assert_equal 1, result[1].line, "call should have line number"
|
595
|
+
assert_equal 1, result[2].line, "masgn should have line number"
|
596
|
+
assert_equal 2, result[3].line, "call should have line number"
|
597
|
+
end
|
598
|
+
|
599
|
+
def test_parse_line_defn_no_parens
|
600
|
+
pt = s(:defn, :f, s(:args), s(:nil))
|
601
|
+
|
602
|
+
rb = "def f\nend"
|
603
|
+
assert_parse_line rb, pt, 1
|
604
|
+
|
605
|
+
rb = "def f\n\nend"
|
606
|
+
assert_parse_line rb, pt, 1
|
607
|
+
end
|
608
|
+
|
609
|
+
def test_parse_line_defn_complex
|
610
|
+
rb = "def x(y)\n p(y)\n y *= 2\n return y;\nend" # TODO: remove () & ;
|
611
|
+
pt = s(:defn, :x, s(:args, :y),
|
612
|
+
s(:call, nil, :p, s(:lvar, :y)),
|
613
|
+
s(:lasgn, :y, s(:call, s(:lvar, :y), :*, s(:lit, 2))),
|
614
|
+
s(:return, s(:lvar, :y)))
|
615
|
+
|
616
|
+
assert_parse_line rb, pt, 1
|
617
|
+
|
618
|
+
body = result
|
619
|
+
assert_equal 2, body.call.line, "call should have line number"
|
620
|
+
assert_equal 3, body.lasgn.line, "lasgn should have line number"
|
621
|
+
assert_equal 4, body.return.line, "return should have line number"
|
622
|
+
end
|
623
|
+
|
624
|
+
def test_parse_line_iter_call_parens
|
625
|
+
rb = "f(a) do |x, y|\n x + y\nend"
|
626
|
+
|
627
|
+
pt = s(:iter,
|
628
|
+
s(:call, nil, :f, s(:call, nil, :a)),
|
629
|
+
s(:args, :x, :y),
|
630
|
+
s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
|
631
|
+
|
632
|
+
assert_parse_line rb, pt, 1
|
633
|
+
|
634
|
+
assert_equal 1, result[1].line, "call should have line number"
|
635
|
+
assert_equal 1, result[2].line, "masgn should have line number"
|
636
|
+
assert_equal 2, result[3].line, "call should have line number"
|
637
|
+
end
|
638
|
+
|
639
|
+
def test_parse_line_iter_call_no_parens
|
640
|
+
rb = "f a do |x, y|\n x + y\nend"
|
641
|
+
|
642
|
+
pt = s(:iter,
|
643
|
+
s(:call, nil, :f, s(:call, nil, :a)),
|
644
|
+
s(:args, :x, :y),
|
645
|
+
s(:call, s(:lvar, :x), :+, s(:lvar, :y)))
|
646
|
+
|
647
|
+
assert_parse_line rb, pt, 1
|
648
|
+
|
649
|
+
assert_equal 1, result[1].line, "call should have line number"
|
650
|
+
assert_equal 1, result[2].line, "masgn should have line number"
|
651
|
+
assert_equal 2, result[3].line, "call should have line number"
|
652
|
+
end
|
653
|
+
|
654
|
+
def test_parse_line_heredoc
|
655
|
+
rb = <<-CODE
|
656
|
+
string = <<-HEREDOC
|
657
|
+
very long string
|
658
|
+
HEREDOC
|
659
|
+
puts string
|
660
|
+
CODE
|
661
|
+
|
662
|
+
pt = s(:block,
|
663
|
+
s(:lasgn, :string,
|
664
|
+
s(:str, " very long string\n").line(1)).line(1),
|
665
|
+
s(:call, nil, :puts, s(:lvar, :string).line(4)).line(4)).line(1)
|
666
|
+
|
667
|
+
assert_parse rb, pt
|
668
|
+
end
|
669
|
+
|
670
|
+
def test_parse_line_newlines
|
671
|
+
rb = "true\n\n"
|
672
|
+
pt = s(:true)
|
673
|
+
|
674
|
+
assert_parse_line rb, pt, 1
|
675
|
+
end
|
676
|
+
|
677
|
+
def test_parse_line_return
|
678
|
+
rb = <<-RUBY
|
679
|
+
def blah
|
680
|
+
if true then
|
681
|
+
return 42
|
682
|
+
end
|
683
|
+
end
|
684
|
+
RUBY
|
685
|
+
|
686
|
+
pt = s(:defn, :blah, s(:args),
|
687
|
+
s(:if, s(:true),
|
688
|
+
s(:return, s(:lit, 42)),
|
689
|
+
nil))
|
690
|
+
|
691
|
+
assert_parse_line rb, pt, 1
|
692
|
+
|
693
|
+
assert_equal 3, result.if.return.line
|
694
|
+
assert_equal 3, result.if.return.lit.line
|
695
|
+
end
|
696
|
+
|
697
|
+
def test_bug_and
|
698
|
+
rb = "true and []"
|
699
|
+
pt = s(:and, s(:true), s(:array))
|
700
|
+
|
701
|
+
assert_parse rb, pt
|
702
|
+
|
703
|
+
rb = "true and\ntrue"
|
704
|
+
pt = s(:and, s(:true), s(:true))
|
705
|
+
|
706
|
+
assert_parse rb, pt
|
707
|
+
end
|
708
|
+
|
709
|
+
def test_bug_cond_pct
|
710
|
+
rb = "case; when %r%blahblah%; end"
|
711
|
+
pt = s(:case, nil, s(:when, s(:array, s(:lit, /blahblah/)), nil), nil)
|
712
|
+
|
713
|
+
assert_parse rb, pt
|
714
|
+
end
|
715
|
+
|
716
|
+
# according to 2.3.1 parser -- added: ON 1.8 only:
|
717
|
+
# rp.process("f { |(a,b),c| }") == rp.process("f { |((a,b),c)| }")
|
718
|
+
|
719
|
+
# ruby18 -e "p lambda { |(a,b)| }.arity" # => 2
|
720
|
+
# ruby19 -e "p lambda { |(a,b)| }.arity" # => 1
|
721
|
+
# ruby18 -e "p lambda { |(a,b),c| }.arity" # => 2
|
722
|
+
# ruby19 -e "p lambda { |(a,b),c| }.arity" # => 2
|
723
|
+
# ruby18 -e "p lambda { |((a,b),c)| }.arity" # => 2
|
724
|
+
# ruby19 -e "p lambda { |((a,b),c)| }.arity" # => 1
|
725
|
+
|
726
|
+
def test_bug_args_masgn
|
727
|
+
rb = "f { |(a, b), c| }"
|
728
|
+
pt = s(:iter,
|
729
|
+
s(:call, nil, :f),
|
730
|
+
s(:args, s(:masgn, :a, :b), :c))
|
731
|
+
|
732
|
+
assert_parse rb, pt.dup
|
733
|
+
end
|
734
|
+
|
735
|
+
def test_bug_args_masgn2
|
736
|
+
rb = "f { |((a, b), c), d| }"
|
737
|
+
pt = s(:iter,
|
738
|
+
s(:call, nil, :f),
|
739
|
+
s(:args, s(:masgn, s(:masgn, :a, :b), :c), :d))
|
740
|
+
|
741
|
+
assert_parse rb, pt
|
742
|
+
end
|
743
|
+
|
744
|
+
def ruby18
|
745
|
+
Ruby18Parser === self.processor
|
746
|
+
end
|
747
|
+
|
748
|
+
def ruby19
|
749
|
+
Ruby19Parser === self.processor
|
750
|
+
end
|
751
|
+
|
752
|
+
def test_bug_comma
|
753
|
+
val = if ruby18 then
|
754
|
+
s(:lit, 100)
|
755
|
+
elsif ruby19 then
|
756
|
+
s(:str, "d")
|
757
|
+
else
|
758
|
+
raise "wtf"
|
759
|
+
end
|
760
|
+
|
761
|
+
rb = "if test ?d, dir then end"
|
762
|
+
pt = s(:if,
|
763
|
+
s(:call, nil, :test, val, s(:call, nil, :dir)),
|
764
|
+
nil,
|
765
|
+
nil)
|
766
|
+
|
767
|
+
assert_parse rb, pt
|
768
|
+
end
|
769
|
+
|
770
|
+
def test_bug_case_when_regexp
|
771
|
+
rb = "case :x; when /x/ then end"
|
772
|
+
pt = s(:case, s(:lit, :x),
|
773
|
+
s(:when, s(:array, s(:lit, /x/)), nil),
|
774
|
+
nil)
|
775
|
+
|
776
|
+
assert_parse rb, pt
|
777
|
+
end
|
778
|
+
|
779
|
+
def test_bug_masgn_right
|
780
|
+
rb = "f { |a, (b, c)| }"
|
781
|
+
pt = s(:iter,
|
782
|
+
s(:call, nil, :f),
|
783
|
+
s(:args, :a, s(:masgn, :b, :c)))
|
784
|
+
|
785
|
+
assert_parse rb, pt
|
786
|
+
end
|
787
|
+
|
788
|
+
def test_when_splat
|
789
|
+
rb = "case a; when *b then; end"
|
790
|
+
pt = s(:case, s(:call, nil, :a),
|
791
|
+
s(:when, s(:array, s(:splat, s(:call, nil, :b))), nil),
|
792
|
+
nil)
|
793
|
+
|
794
|
+
assert_parse rb, pt
|
795
|
+
end
|
796
|
+
|
797
|
+
def test_if_symbol
|
798
|
+
rb = "if f :x; end"
|
799
|
+
pt = s(:if, s(:call, nil, :f, s(:lit, :x)), nil, nil)
|
800
|
+
|
801
|
+
assert_parse rb, pt
|
802
|
+
end
|
803
|
+
|
804
|
+
|
805
|
+
def test_bug_not_parens
|
806
|
+
rb = "not(a)"
|
807
|
+
pt = if ruby18 then
|
808
|
+
s(:not, s(:call, nil, :a))
|
809
|
+
elsif ruby19 then
|
810
|
+
s(:call, s(:call, nil, :a), :"!")
|
811
|
+
else
|
812
|
+
raise "wtf"
|
813
|
+
end
|
814
|
+
|
815
|
+
assert_parse rb, pt
|
816
|
+
end
|
817
|
+
|
818
|
+
def test_pipe_space
|
819
|
+
rb = "a.b do | | end"
|
820
|
+
pt = s(:iter, s(:call, s(:call, nil, :a), :b), 0)
|
821
|
+
|
822
|
+
assert_parse rb, pt
|
823
|
+
end
|
824
|
+
|
825
|
+
def test_cond_unary_minus
|
826
|
+
rb = "if -1; end"
|
827
|
+
pt = s(:if, s(:lit, -1), nil, nil)
|
828
|
+
|
829
|
+
assert_parse rb, pt
|
830
|
+
end
|
831
|
+
|
832
|
+
def test_bug_op_asgn_rescue
|
833
|
+
rb = "a ||= b rescue nil"
|
834
|
+
pt = s(:rescue,
|
835
|
+
s(:op_asgn_or, s(:lvar, :a), s(:lasgn, :a, s(:call, nil, :b))),
|
836
|
+
s(:resbody, s(:array), s(:nil)))
|
837
|
+
|
838
|
+
assert_parse rb, pt
|
839
|
+
end
|
840
|
+
|
841
|
+
def test_magic_encoding_comment
|
842
|
+
rb = "# encoding: utf-8\nclass ExampleUTF8ClassNameVarietà; def self.è; così = :però; end\nend\n"
|
843
|
+
|
844
|
+
rb.force_encoding "ASCII-8BIT" if rb.respond_to? :force_encoding
|
845
|
+
|
846
|
+
# TODO: class vars
|
847
|
+
# TODO: odd-ternary: a ?bb : c
|
848
|
+
# TODO: globals
|
849
|
+
|
850
|
+
pt = s(:class, :"ExampleUTF8ClassNameVariet\303\240", nil,
|
851
|
+
s(:defs, s(:self), :"\303\250", s(:args),
|
852
|
+
s(:lasgn, :"cos\303\254", s(:lit, :"per\303\262"))))
|
853
|
+
|
854
|
+
err = RUBY_VERSION =~ /^1\.8/ ? "Skipping magic encoding comment\n" : ""
|
855
|
+
|
856
|
+
assert_output "", err do
|
857
|
+
assert_parse rb, pt
|
858
|
+
end
|
859
|
+
end
|
860
|
+
|
861
|
+
def test_iter_args_1
|
862
|
+
rb = "f { |a,b| }"
|
863
|
+
pt = s(:iter, s(:call, nil, :f), s(:args, :a, :b))
|
864
|
+
|
865
|
+
assert_parse rb, pt
|
866
|
+
end
|
867
|
+
|
868
|
+
def test_iter_args_3
|
869
|
+
rb = "f { |a, (b, c), d| }"
|
870
|
+
pt = s(:iter, s(:call, nil, :f), s(:args, :a, s(:masgn, :b, :c), :d))
|
871
|
+
|
872
|
+
assert_parse rb, pt
|
873
|
+
end
|
874
|
+
|
875
|
+
def test_str_heredoc_interp
|
876
|
+
rb = "<<\"\"\n\#{x}\nblah2\n\n"
|
877
|
+
pt = s(:dstr, "", s(:evstr, s(:call, nil, :x)), s(:str, "\n"), s(:str, "blah2\n"))
|
878
|
+
|
879
|
+
assert_parse rb, pt
|
880
|
+
end
|
881
|
+
|
882
|
+
def test_i_fucking_hate_line_numbers
|
883
|
+
rb = <<-END.gsub(/^ {6}/, '')
|
884
|
+
if true
|
885
|
+
p 1
|
886
|
+
a.b 2
|
887
|
+
c.d 3, 4
|
888
|
+
e.f 5
|
889
|
+
g.h 6, 7
|
890
|
+
p(1)
|
891
|
+
a.b(2)
|
892
|
+
c.d(3, 4)
|
893
|
+
e.f(5)
|
894
|
+
g.h(6, 7)
|
895
|
+
end
|
896
|
+
END
|
897
|
+
|
898
|
+
pt = s(:if, s(:true).line(1),
|
899
|
+
s(:block,
|
900
|
+
s(:call, nil, :p, s(:lit, 1).line(2)).line(2),
|
901
|
+
s(:call, s(:call, nil, :a).line(3), :b,
|
902
|
+
s(:lit, 2).line(3)).line(3),
|
903
|
+
s(:call, s(:call, nil, :c).line(4), :d,
|
904
|
+
s(:lit, 3).line(4), s(:lit, 4).line(4)).line(4),
|
905
|
+
s(:call, s(:call, nil, :e).line(5), :f,
|
906
|
+
s(:lit, 5).line(5)).line(5),
|
907
|
+
s(:call, s(:call, nil, :g).line(6), :h,
|
908
|
+
s(:lit, 6).line(6), s(:lit, 7).line(6)).line(6),
|
909
|
+
s(:call, nil, :p, s(:lit, 1).line(7)).line(7),
|
910
|
+
s(:call, s(:call, nil, :a).line(8), :b,
|
911
|
+
s(:lit, 2).line(8)).line(8),
|
912
|
+
s(:call, s(:call, nil, :c).line(9), :d,
|
913
|
+
s(:lit, 3).line(9), s(:lit, 4).line(9)).line(9),
|
914
|
+
s(:call, s(:call, nil, :e).line(10), :f,
|
915
|
+
s(:lit, 5).line(10)).line(10),
|
916
|
+
s(:call, s(:call, nil, :g).line(11), :h,
|
917
|
+
s(:lit, 6).line(11), s(:lit, 7).line(11)).line(11)).line(2),
|
918
|
+
nil).line(1)
|
919
|
+
|
920
|
+
assert_parse rb, pt
|
921
|
+
end
|
922
|
+
|
923
|
+
def test_i_fucking_hate_line_numbers2
|
924
|
+
rb = <<-EOM.gsub(/^ {6}/, '')
|
925
|
+
if true then
|
926
|
+
p('a')
|
927
|
+
b = 1
|
928
|
+
p b
|
929
|
+
c =1
|
930
|
+
end
|
931
|
+
a
|
932
|
+
EOM
|
933
|
+
|
934
|
+
pt = s(:block,
|
935
|
+
s(:if, s(:true).line(1),
|
936
|
+
s(:block,
|
937
|
+
s(:call, nil, :p, s(:str, "a").line(2)).line(2),
|
938
|
+
s(:lasgn, :b, s(:lit, 1).line(3)).line(3),
|
939
|
+
s(:call, nil, :p, s(:lvar, :b).line(4)).line(4),
|
940
|
+
s(:lasgn, :c, s(:lit, 1).line(5)).line(5)).line(2), # TODO line 2?
|
941
|
+
nil).line(1),
|
942
|
+
s(:call, nil, :a).line(7)).line(1)
|
943
|
+
|
944
|
+
assert_parse rb, pt
|
945
|
+
end
|
946
|
+
|
947
|
+
def test_parse_comments
|
948
|
+
p = RubyParser.new
|
949
|
+
sexp = p.parse <<-CODE
|
950
|
+
# class comment
|
951
|
+
class Inline
|
952
|
+
def show
|
953
|
+
# woot
|
954
|
+
end
|
955
|
+
|
956
|
+
# Returns a list of things
|
957
|
+
def list
|
958
|
+
# woot
|
959
|
+
end
|
960
|
+
end
|
961
|
+
CODE
|
962
|
+
|
963
|
+
assert_equal "# class comment\n", sexp.comments
|
964
|
+
act = sexp.find_nodes(:defn).map(&:comments)
|
965
|
+
exp = ["", "# Returns a list of things\n"]
|
966
|
+
|
967
|
+
assert_equal exp, act
|
968
|
+
assert_equal [], processor.comments
|
969
|
+
assert_equal "", processor.lexer.comments
|
970
|
+
end
|
971
|
+
end
|
972
|
+
|
973
|
+
class TestRubyParser < MiniTest::Unit::TestCase
|
974
|
+
def test_parse
|
975
|
+
processor = RubyParser.new
|
976
|
+
|
977
|
+
# 1.8 only syntax
|
978
|
+
rb = "while false : 42 end"
|
979
|
+
pt = s(:while, s(:false), s(:lit, 42), true)
|
980
|
+
|
981
|
+
assert_silent do
|
982
|
+
assert_equal pt, processor.parse(rb)
|
983
|
+
end
|
984
|
+
|
985
|
+
# 1.9 only syntax
|
986
|
+
rb = "a.()"
|
987
|
+
pt = s(:call, s(:call, nil, :a), :call)
|
988
|
+
|
989
|
+
assert_equal pt, processor.parse(rb)
|
990
|
+
|
991
|
+
# bad syntax
|
992
|
+
e = assert_raises Racc::ParseError do
|
993
|
+
capture_io do
|
994
|
+
processor.parse "a.("
|
995
|
+
end
|
996
|
+
end
|
997
|
+
|
998
|
+
msg = "(string):1 :: parse error on value \"(\" (tLPAREN2)"
|
999
|
+
assert_equal msg, e.message.strip
|
1000
|
+
end
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
class TestRuby18Parser < RubyParserTestCase
|
1004
|
+
include TestRubyParserShared
|
1005
|
+
|
1006
|
+
def setup
|
1007
|
+
super
|
1008
|
+
|
1009
|
+
self.processor = Ruby18Parser.new
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
def test_flip2_env_lvar
|
1013
|
+
rb = "if a..b then end"
|
1014
|
+
pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
|
1015
|
+
|
1016
|
+
assert_parse rb, pt
|
1017
|
+
|
1018
|
+
top_env = processor.env.env.first
|
1019
|
+
|
1020
|
+
assert_kind_of Hash, top_env
|
1021
|
+
|
1022
|
+
flip = top_env.find { |k,v| k =~ /^flip/ }
|
1023
|
+
|
1024
|
+
assert flip
|
1025
|
+
assert_equal :lvar, flip.last
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
def test_assoc_list_18
|
1029
|
+
rb = "{1, 2, 3, 4}"
|
1030
|
+
pt = s(:hash, s(:lit, 1), s(:lit, 2), s(:lit, 3), s(:lit, 4))
|
1031
|
+
|
1032
|
+
assert_parse rb, pt
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
def test_case_then_colon_18
|
1036
|
+
rb = "case x; when Fixnum: 42; end"
|
1037
|
+
pt = s(:case,
|
1038
|
+
s(:call, nil, :x),
|
1039
|
+
s(:when, s(:array, s(:const, :Fixnum)), s(:lit, 42)),
|
1040
|
+
nil)
|
1041
|
+
|
1042
|
+
assert_parse rb, pt
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
def test_do_colon_18
|
1046
|
+
rb = "while false : 42 end"
|
1047
|
+
pt = s(:while, s(:false), s(:lit, 42), true)
|
1048
|
+
|
1049
|
+
assert_parse rb, pt
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
def test_parse_until_not_canonical
|
1053
|
+
rb = "until not var.nil?\n 'foo'\nend"
|
1054
|
+
|
1055
|
+
pt = s(:while,
|
1056
|
+
s(:call, s(:call, nil, :var), :nil?),
|
1057
|
+
s(:str, "foo"), true)
|
1058
|
+
|
1059
|
+
assert_parse rb, pt
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
def test_parse_until_not_noncanonical
|
1063
|
+
rb = "until not var.nil?\n 'foo'\nend"
|
1064
|
+
pt = s(:until,
|
1065
|
+
s(:not, s(:call, s(:call, nil, :var), :nil?)),
|
1066
|
+
s(:str, "foo"), true)
|
1067
|
+
|
1068
|
+
processor.canonicalize_conditions = false
|
1069
|
+
|
1070
|
+
assert_parse rb, pt
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
def test_parse_if_not_canonical
|
1074
|
+
rb = "if not var.nil? then 'foo' else 'bar'\nend"
|
1075
|
+
pt = s(:if,
|
1076
|
+
s(:call, s(:call, nil, :var), :nil?),
|
1077
|
+
s(:str, "bar"),
|
1078
|
+
s(:str, "foo"))
|
1079
|
+
|
1080
|
+
assert_parse rb, pt
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
def test_parse_if_not_noncanonical
|
1084
|
+
rb = "if not var.nil? then 'foo' else 'bar'\nend"
|
1085
|
+
pt = s(:if,
|
1086
|
+
s(:not, s(:call, s(:call, nil, :var), :nil?)),
|
1087
|
+
s(:str, "foo"),
|
1088
|
+
s(:str, "bar"))
|
1089
|
+
|
1090
|
+
processor.canonicalize_conditions = false
|
1091
|
+
|
1092
|
+
assert_parse rb, pt
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
def test_parse_while_not_canonical
|
1096
|
+
rb = "while not var.nil?\n 'foo'\nend"
|
1097
|
+
pt = s(:until,
|
1098
|
+
s(:call, s(:call, nil, :var), :nil?),
|
1099
|
+
s(:str, "foo"), true)
|
1100
|
+
|
1101
|
+
assert_parse rb, pt
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
def test_parse_while_not_noncanonical
|
1105
|
+
rb = "while not var.nil?\n 'foo'\nend"
|
1106
|
+
pt = s(:while,
|
1107
|
+
s(:not, s(:call, s(:call, nil, :var), :nil?)),
|
1108
|
+
s(:str, "foo"), true)
|
1109
|
+
|
1110
|
+
processor.canonicalize_conditions = false
|
1111
|
+
|
1112
|
+
assert_parse rb, pt
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
def test_double_block_error_10
|
1116
|
+
assert_syntax_error "a.b (&b) {}", BLOCK_DUP_MSG
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
def test_double_block_error_11
|
1120
|
+
assert_syntax_error "a (1, &b) { }", BLOCK_DUP_MSG
|
1121
|
+
end
|
1122
|
+
|
1123
|
+
def test_double_block_error_12
|
1124
|
+
assert_syntax_error "a (1, &b) do end", BLOCK_DUP_MSG
|
1125
|
+
end
|
1126
|
+
|
1127
|
+
def test_double_block_error_13
|
1128
|
+
assert_syntax_error "m.a (1, &b) { }", BLOCK_DUP_MSG
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
def test_double_block_error_14
|
1132
|
+
assert_syntax_error "m.a (1, &b) do end", BLOCK_DUP_MSG
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
def test_double_block_error_15
|
1136
|
+
assert_syntax_error "m::a (1, &b) { }", BLOCK_DUP_MSG
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
def test_double_block_error_16
|
1140
|
+
assert_syntax_error "m::a (1, &b) do end", BLOCK_DUP_MSG
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
# In 1.8, block args with an outer set of parens are superfluous.
|
1144
|
+
# In 1.9, outer set of parens are NOT... they are an explicit extra masgn.
|
1145
|
+
|
1146
|
+
def test_iter_args_2_18
|
1147
|
+
rb = "f { |(a, b)| }"
|
1148
|
+
pt = s(:iter, s(:call, nil, :f), s(:args, :a, :b))
|
1149
|
+
|
1150
|
+
assert_parse rb, pt
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
def test_bug_args__18
|
1154
|
+
rb = "f { |(a, b)| }"
|
1155
|
+
pt = s(:iter, s(:call, nil, :f),
|
1156
|
+
s(:args, :a, :b))
|
1157
|
+
|
1158
|
+
assert_parse rb, pt
|
1159
|
+
end
|
1160
|
+
|
1161
|
+
def test_bug_args_masgn_outer_parens__18
|
1162
|
+
rb = "f { |((a, b), c)| }"
|
1163
|
+
pt = s(:iter, # NOTE: same sexp as test_bug_args_masgn
|
1164
|
+
s(:call, nil, :f),
|
1165
|
+
s(:args, s(:masgn, :a, :b), :c))
|
1166
|
+
|
1167
|
+
assert_parse rb, pt.dup
|
1168
|
+
end
|
1169
|
+
end
|
1170
|
+
|
1171
|
+
class TestRuby19Parser < RubyParserTestCase
|
1172
|
+
include TestRubyParserShared
|
1173
|
+
|
1174
|
+
def setup
|
1175
|
+
super
|
1176
|
+
|
1177
|
+
self.processor = Ruby19Parser.new
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
def test_mlhs_back_splat
|
1181
|
+
rb = "a, b, c, *s = f"
|
1182
|
+
pt = s(:masgn,
|
1183
|
+
s(:array,
|
1184
|
+
s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
|
1185
|
+
s(:splat, s(:lasgn, :s))),
|
1186
|
+
s(:to_ary, s(:call, nil, :f)))
|
1187
|
+
|
1188
|
+
assert_parse rb, pt
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
def test_mlhs_back_anonsplat
|
1192
|
+
rb = "a, b, c, * = f"
|
1193
|
+
pt = s(:masgn,
|
1194
|
+
s(:array,
|
1195
|
+
s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
|
1196
|
+
s(:splat)),
|
1197
|
+
s(:to_ary, s(:call, nil, :f)))
|
1198
|
+
|
1199
|
+
assert_parse rb, pt
|
1200
|
+
end
|
1201
|
+
|
1202
|
+
def test_mlhs_mid_splat
|
1203
|
+
rb = "a, b, c, *s, x, y, z = f"
|
1204
|
+
pt = s(:masgn,
|
1205
|
+
s(:array,
|
1206
|
+
s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
|
1207
|
+
s(:splat, s(:lasgn, :s)),
|
1208
|
+
s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
|
1209
|
+
s(:to_ary, s(:call, nil, :f)))
|
1210
|
+
|
1211
|
+
assert_parse rb, pt
|
1212
|
+
end
|
1213
|
+
|
1214
|
+
def test_mlhs_mid_anonsplat
|
1215
|
+
rb = "a, b, c, *, x, y, z = f"
|
1216
|
+
pt = s(:masgn,
|
1217
|
+
s(:array, s(:lasgn, :a), s(:splat), s(:lasgn, :z)),
|
1218
|
+
s(:to_ary, s(:call, nil, :f)))
|
1219
|
+
pt = s(:masgn,
|
1220
|
+
s(:array,
|
1221
|
+
s(:lasgn, :a), s(:lasgn, :b), s(:lasgn, :c),
|
1222
|
+
s(:splat),
|
1223
|
+
s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
|
1224
|
+
s(:to_ary, s(:call, nil, :f)))
|
1225
|
+
|
1226
|
+
assert_parse rb, pt
|
1227
|
+
end
|
1228
|
+
|
1229
|
+
def test_mlhs_front_splat
|
1230
|
+
rb = "*s, x, y, z = f"
|
1231
|
+
pt = s(:masgn,
|
1232
|
+
s(:array, s(:splat, s(:lasgn, :s)), s(:lasgn, :z)),
|
1233
|
+
s(:to_ary, s(:call, nil, :f)))
|
1234
|
+
pt = s(:masgn,
|
1235
|
+
s(:array,
|
1236
|
+
s(:splat, s(:lasgn, :s)),
|
1237
|
+
s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
|
1238
|
+
s(:to_ary, s(:call, nil, :f)))
|
1239
|
+
|
1240
|
+
assert_parse rb, pt
|
1241
|
+
end
|
1242
|
+
|
1243
|
+
def test_mlhs_front_anonsplat
|
1244
|
+
rb = "*, x, y, z = f"
|
1245
|
+
pt = s(:masgn,
|
1246
|
+
s(:array,
|
1247
|
+
s(:splat),
|
1248
|
+
s(:lasgn, :x), s(:lasgn, :y), s(:lasgn, :z)),
|
1249
|
+
s(:to_ary, s(:call, nil, :f)))
|
1250
|
+
|
1251
|
+
assert_parse rb, pt
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
def test_expr_not_bang
|
1255
|
+
rb = "! a b"
|
1256
|
+
pt = s(:call, s(:call, nil, :a, s(:call, nil, :b)), :"!")
|
1257
|
+
|
1258
|
+
assert_parse rb, pt
|
1259
|
+
end
|
1260
|
+
|
1261
|
+
def test_encoding
|
1262
|
+
rb = '__ENCODING__'
|
1263
|
+
pt = if defined? Encoding then
|
1264
|
+
s(:const, Encoding::UTF_8)
|
1265
|
+
else
|
1266
|
+
s(:str, "Unsupported!")
|
1267
|
+
end
|
1268
|
+
|
1269
|
+
assert_parse rb, pt
|
1270
|
+
end
|
1271
|
+
|
1272
|
+
def test_do_colon_19
|
1273
|
+
rb = "while false : 42 end"
|
1274
|
+
|
1275
|
+
assert_parse_error rb, "(string):1 :: parse error on value \":\" (tCOLON)"
|
1276
|
+
end
|
1277
|
+
|
1278
|
+
def test_assoc_list_19
|
1279
|
+
rb = "{1, 2, 3, 4}"
|
1280
|
+
|
1281
|
+
assert_parse_error rb, "(string):1 :: parse error on value \",\" (tCOMMA)"
|
1282
|
+
end
|
1283
|
+
|
1284
|
+
def test_case_then_colon_19
|
1285
|
+
rb = <<-EOM
|
1286
|
+
case x
|
1287
|
+
when Fixnum : # need the space to not hit new hash arg syntax
|
1288
|
+
42
|
1289
|
+
end
|
1290
|
+
EOM
|
1291
|
+
|
1292
|
+
assert_parse_error rb, "(string):2 :: parse error on value \":\" (tCOLON)"
|
1293
|
+
end
|
1294
|
+
|
1295
|
+
def test_parse_def_xxx1
|
1296
|
+
rb = 'def f(a, *b, c = nil) end'
|
1297
|
+
|
1298
|
+
assert_parse_error rb, '(string):1 :: parse error on value "=" (tEQL)'
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
def test_parse_def_xxx2
|
1302
|
+
rb = 'def f(a = nil, *b, c = nil) end'
|
1303
|
+
|
1304
|
+
assert_parse_error rb, '(string):1 :: parse error on value "=" (tEQL)'
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
def test_parse_until_not_canonical
|
1308
|
+
rb = "until not var.nil?\n 'foo'\nend"
|
1309
|
+
pt = s(:until,
|
1310
|
+
s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
|
1311
|
+
s(:str, "foo"), true)
|
1312
|
+
|
1313
|
+
assert_parse rb, pt
|
1314
|
+
end
|
1315
|
+
|
1316
|
+
def test_parse_until_not_noncanonical
|
1317
|
+
rb = "until not var.nil?\n 'foo'\nend"
|
1318
|
+
pt = s(:until,
|
1319
|
+
s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
|
1320
|
+
s(:str, "foo"), true)
|
1321
|
+
|
1322
|
+
processor.canonicalize_conditions = false
|
1323
|
+
|
1324
|
+
assert_parse rb, pt
|
1325
|
+
end
|
1326
|
+
|
1327
|
+
def test_parse_if_not_canonical
|
1328
|
+
rb = "if not var.nil? then 'foo' else 'bar'\nend"
|
1329
|
+
pt = s(:if,
|
1330
|
+
s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
|
1331
|
+
s(:str, "foo"),
|
1332
|
+
s(:str, "bar"))
|
1333
|
+
|
1334
|
+
assert_parse rb, pt
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
def test_parse_if_not_noncanonical
|
1338
|
+
rb = "if not var.nil? then 'foo' else 'bar'\nend"
|
1339
|
+
pt = s(:if,
|
1340
|
+
s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
|
1341
|
+
s(:str, "foo"),
|
1342
|
+
s(:str, "bar"))
|
1343
|
+
|
1344
|
+
processor.canonicalize_conditions = false
|
1345
|
+
|
1346
|
+
assert_parse rb, pt
|
1347
|
+
end
|
1348
|
+
|
1349
|
+
def test_parse_while_not_canonical
|
1350
|
+
rb = "while not var.nil?\n 'foo'\nend"
|
1351
|
+
pt = s(:while,
|
1352
|
+
s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
|
1353
|
+
s(:str, "foo"), true)
|
1354
|
+
|
1355
|
+
assert_parse rb, pt
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
def test_parse_while_not_noncanonical
|
1359
|
+
rb = "while not var.nil?\n 'foo'\nend"
|
1360
|
+
pt = s(:while,
|
1361
|
+
s(:call, s(:call, s(:call, nil, :var), :nil?), :"!"),
|
1362
|
+
s(:str, "foo"), true)
|
1363
|
+
|
1364
|
+
processor.canonicalize_conditions = false
|
1365
|
+
|
1366
|
+
assert_parse rb, pt
|
1367
|
+
end
|
1368
|
+
|
1369
|
+
def test_parse_opt_call_args_assocs_comma
|
1370
|
+
rb = "1[2=>3,]"
|
1371
|
+
pt = s(:call, s(:lit, 1), :[], s(:lit, 2), s(:lit, 3))
|
1372
|
+
|
1373
|
+
assert_parse rb, pt
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
def test_bug_hash_args
|
1377
|
+
rb = "foo(:bar, baz: nil)"
|
1378
|
+
pt = s(:call, nil, :foo,
|
1379
|
+
s(:lit, :bar),
|
1380
|
+
s(:hash, s(:lit, :baz), s(:nil)))
|
1381
|
+
|
1382
|
+
assert_parse rb, pt
|
1383
|
+
end
|
1384
|
+
|
1385
|
+
def test_bug_hash_args_trailing_comma
|
1386
|
+
rb = "foo(:bar, baz: nil,)"
|
1387
|
+
pt = s(:call, nil, :foo, # NOTE: same sexp as test_bug_hash_args
|
1388
|
+
s(:lit, :bar),
|
1389
|
+
s(:hash, s(:lit, :baz), s(:nil)))
|
1390
|
+
|
1391
|
+
assert_parse rb, pt
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
def test_block_arg_optional
|
1395
|
+
rb = "a { |b = 1| }"
|
1396
|
+
pt = s(:iter,
|
1397
|
+
s(:call, nil, :a),
|
1398
|
+
s(:args, s(:lasgn, :b, s(:lit, 1))))
|
1399
|
+
|
1400
|
+
assert_parse rb, pt
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
def test_zomg_sometimes_i_hate_this_project
|
1404
|
+
rb = <<-RUBY
|
1405
|
+
{
|
1406
|
+
a: lambda { b ? c() : d },
|
1407
|
+
e: nil,
|
1408
|
+
}
|
1409
|
+
RUBY
|
1410
|
+
|
1411
|
+
pt = s(:hash,
|
1412
|
+
s(:lit, :a),
|
1413
|
+
s(:iter,
|
1414
|
+
s(:call, nil, :lambda),
|
1415
|
+
s(:args),
|
1416
|
+
s(:if, s(:call, nil, :b), s(:call, nil, :c), s(:call, nil, :d))),
|
1417
|
+
|
1418
|
+
s(:lit, :e),
|
1419
|
+
s(:nil))
|
1420
|
+
|
1421
|
+
assert_parse rb, pt
|
1422
|
+
end
|
1423
|
+
|
1424
|
+
# def test_pipe_semicolon # HACK
|
1425
|
+
# rb = "a.b do | ; c | end"
|
1426
|
+
# pt = s(:iter, s(:call, s(:call, nil, :a), :b), 0)
|
1427
|
+
#
|
1428
|
+
# assert_parse rb, pt
|
1429
|
+
# end
|
1430
|
+
|
1431
|
+
def test_wtf
|
1432
|
+
# lambda -> f_larglist lambda_body
|
1433
|
+
# f_larglist -> f_args opt_bv_decl
|
1434
|
+
# opt_bv_decl
|
1435
|
+
# bv_decls
|
1436
|
+
# bvar
|
1437
|
+
|
1438
|
+
rb = "->(a, b=nil) { p [a, b] }"
|
1439
|
+
pt = s(:iter,
|
1440
|
+
s(:call, nil, :lambda),
|
1441
|
+
s(:args, :a, s(:lasgn, :b, s(:nil))),
|
1442
|
+
s(:call, nil, :p, s(:array, s(:lvar, :a), s(:lvar, :b))))
|
1443
|
+
|
1444
|
+
assert_parse rb, pt
|
1445
|
+
|
1446
|
+
# rb = "->(a; b) { p [a, b] }"
|
1447
|
+
#
|
1448
|
+
# assert_parse rb, pt
|
1449
|
+
end
|
1450
|
+
|
1451
|
+
def test_block_args_opt1
|
1452
|
+
rb = "f { |a, b = 42| [a, b] }"
|
1453
|
+
pt = s(:iter,
|
1454
|
+
s(:call, nil, :f),
|
1455
|
+
s(:args, :a, s(:lasgn, :b, s(:lit, 42))),
|
1456
|
+
s(:array, s(:lvar, :a), s(:lvar, :b)))
|
1457
|
+
|
1458
|
+
assert_parse rb, pt
|
1459
|
+
end
|
1460
|
+
|
1461
|
+
def test_block_args_opt2
|
1462
|
+
rb = "f { |a, b = 42, c = 24| [a, b, c] }"
|
1463
|
+
pt = s(:iter,
|
1464
|
+
s(:call, nil, :f),
|
1465
|
+
s(:args, :a, s(:lasgn, :b, s(:lit, 42)), s(:lasgn, :c, s(:lit, 24))),
|
1466
|
+
s(:array, s(:lvar, :a), s(:lvar, :b), s(:lvar, :c)))
|
1467
|
+
|
1468
|
+
assert_parse rb, pt
|
1469
|
+
end
|
1470
|
+
|
1471
|
+
def test_block_args_opt3
|
1472
|
+
rb = "f { |a, b = 42, c = 24, &d| [a, b, c, d] }"
|
1473
|
+
pt = s(:iter,
|
1474
|
+
s(:call, nil, :f),
|
1475
|
+
s(:args, :a, s(:lasgn, :b, s(:lit, 42)), s(:lasgn, :c, s(:lit, 24)), :"&d"),
|
1476
|
+
s(:array, s(:lvar, :a), s(:lvar, :b), s(:lvar, :c), s(:lvar, :d)))
|
1477
|
+
|
1478
|
+
assert_parse rb, pt
|
1479
|
+
end
|
1480
|
+
|
1481
|
+
def test_i_have_no_freakin_clue
|
1482
|
+
rb = "1 ? b('') : 2\na d: 3"
|
1483
|
+
pt = s(:block,
|
1484
|
+
s(:if, s(:lit, 1), s(:call, nil, :b, s(:str, "")), s(:lit, 2)),
|
1485
|
+
s(:call, nil, :a, s(:hash, s(:lit, :d), s(:lit, 3))))
|
1486
|
+
|
1487
|
+
assert_parse rb, pt
|
1488
|
+
end
|
1489
|
+
|
1490
|
+
def test_motherfuckin_leading_dots
|
1491
|
+
rb = "a\n.b"
|
1492
|
+
pt = s(:call, s(:call, nil, :a), :b)
|
1493
|
+
|
1494
|
+
assert_parse rb, pt
|
1495
|
+
end
|
1496
|
+
|
1497
|
+
def test_motherfuckin_leading_dots2
|
1498
|
+
rb = "a\n..b"
|
1499
|
+
|
1500
|
+
assert_parse_error rb, '(string):2 :: parse error on value ".." (tDOT2)'
|
1501
|
+
end
|
1502
|
+
|
1503
|
+
def test_kill_me
|
1504
|
+
rb = "f { |a, (b, *c)| }"
|
1505
|
+
pt = s(:iter,
|
1506
|
+
s(:call, nil, :f),
|
1507
|
+
s(:args, :a, s(:masgn, :b, :"*c")))
|
1508
|
+
|
1509
|
+
assert_parse rb, pt
|
1510
|
+
end
|
1511
|
+
|
1512
|
+
def test_kill_me2
|
1513
|
+
rb = "f { |*a, b| }"
|
1514
|
+
pt = s(:iter, s(:call, nil, :f), s(:args, :"*a", :b))
|
1515
|
+
|
1516
|
+
assert_parse rb, pt
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
def test_kill_me3
|
1520
|
+
rb = "f { |*a, b, &c| }"
|
1521
|
+
pt = s(:iter, s(:call, nil, :f), s(:args, :"*a", :b, :"&c"))
|
1522
|
+
|
1523
|
+
assert_parse rb, pt
|
1524
|
+
end
|
1525
|
+
|
1526
|
+
def test_kill_me4
|
1527
|
+
rb = "a=b ? true: false"
|
1528
|
+
pt = s(:lasgn, :a, s(:if, s(:call, nil, :b), s(:true), s(:false)))
|
1529
|
+
|
1530
|
+
assert_parse rb, pt
|
1531
|
+
end
|
1532
|
+
|
1533
|
+
# def test_kill_me5
|
1534
|
+
# rb = "f ->() { g do end }"
|
1535
|
+
# pt = 42
|
1536
|
+
#
|
1537
|
+
# assert_parse rb, pt
|
1538
|
+
# end
|
1539
|
+
|
1540
|
+
def test_iter_args_4
|
1541
|
+
rb = "f { |a, *b, c| }"
|
1542
|
+
pt = s(:iter, s(:call, nil, :f), s(:args, :a, :"*b", :c))
|
1543
|
+
|
1544
|
+
assert_parse rb, pt
|
1545
|
+
end
|
1546
|
+
|
1547
|
+
def test_iter_args_5
|
1548
|
+
rb = "f { |a, &b| }"
|
1549
|
+
pt = s(:iter, s(:call, nil, :f), s(:args, :a, :"&b"))
|
1550
|
+
|
1551
|
+
assert_parse rb, pt
|
1552
|
+
end
|
1553
|
+
|
1554
|
+
def test_iter_args_6
|
1555
|
+
rb = "f { |a, b=42, c| }"
|
1556
|
+
pt = s(:iter, s(:call, nil, :f), s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :c))
|
1557
|
+
|
1558
|
+
assert_parse rb, pt
|
1559
|
+
end
|
1560
|
+
|
1561
|
+
# In 1.8, block args with an outer set of parens are superfluous.
|
1562
|
+
# In 1.9, outer set of parens are NOT... they are an explicit extra masgn.
|
1563
|
+
|
1564
|
+
def test_iter_args_2__19
|
1565
|
+
rb = "f { |(a, b)| }"
|
1566
|
+
pt = s(:iter, s(:call, nil, :f), s(:args, s(:masgn, :a, :b)))
|
1567
|
+
|
1568
|
+
assert_parse rb, pt
|
1569
|
+
end
|
1570
|
+
|
1571
|
+
def test_bug_args__19
|
1572
|
+
rb = "f { |(a, b)| d }"
|
1573
|
+
pt = s(:iter, s(:call, nil, :f),
|
1574
|
+
s(:args, s(:masgn, :a, :b)),
|
1575
|
+
s(:call, nil, :d))
|
1576
|
+
|
1577
|
+
assert_parse rb, pt
|
1578
|
+
end
|
1579
|
+
|
1580
|
+
def test_bug_args_masgn_outer_parens__19
|
1581
|
+
rb = "f { |((k, v), i)| }"
|
1582
|
+
pt = s(:iter, # NOTE: same sexp as test_bug_args_masgn
|
1583
|
+
s(:call, nil, :f),
|
1584
|
+
s(:args, s(:masgn, s(:masgn, :k, :v), :i)))
|
1585
|
+
|
1586
|
+
assert_parse rb, pt.dup
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
def test_iter_args_7_1
|
1590
|
+
rb = "f { |a = 42, *b| }"
|
1591
|
+
pt = s(:iter, s(:call, nil, :f),
|
1592
|
+
s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b"))
|
1593
|
+
|
1594
|
+
assert_parse rb, pt
|
1595
|
+
end
|
1596
|
+
|
1597
|
+
def test_iter_args_7_2
|
1598
|
+
rb = "f { |a = 42, *b, &c| }"
|
1599
|
+
pt = s(:iter, s(:call, nil, :f),
|
1600
|
+
s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b", :"&c"))
|
1601
|
+
|
1602
|
+
assert_parse rb, pt
|
1603
|
+
end
|
1604
|
+
|
1605
|
+
def test_iter_args_8_1
|
1606
|
+
rb = "f { |a = 42, *b, c| }"
|
1607
|
+
pt = s(:iter, s(:call, nil, :f),
|
1608
|
+
s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b", :c))
|
1609
|
+
|
1610
|
+
assert_parse rb, pt
|
1611
|
+
end
|
1612
|
+
|
1613
|
+
def test_iter_args_8_2
|
1614
|
+
rb = "f { |a = 42, *b, c, &d| }"
|
1615
|
+
pt = s(:iter, s(:call, nil, :f),
|
1616
|
+
s(:args, s(:lasgn, :a, s(:lit, 42)), :"*b", :c, :"&d"))
|
1617
|
+
|
1618
|
+
assert_parse rb, pt
|
1619
|
+
end
|
1620
|
+
|
1621
|
+
def test_iter_args_9_1
|
1622
|
+
rb = "f { |a = 42, b| }"
|
1623
|
+
pt = s(:iter, s(:call, nil, :f),
|
1624
|
+
s(:args, s(:lasgn, :a, s(:lit, 42)), :b))
|
1625
|
+
|
1626
|
+
assert_parse rb, pt
|
1627
|
+
end
|
1628
|
+
|
1629
|
+
def test_iter_args_9_2
|
1630
|
+
rb = "f { |a = 42, b, &c| }"
|
1631
|
+
pt = s(:iter, s(:call, nil, :f),
|
1632
|
+
s(:args, s(:lasgn, :a, s(:lit, 42)), :b, :"&c"))
|
1633
|
+
|
1634
|
+
assert_parse rb, pt
|
1635
|
+
end
|
1636
|
+
|
1637
|
+
def test_iter_args_10_1
|
1638
|
+
rb = "f { |a, b = 42, *c| }"
|
1639
|
+
pt = s(:iter, s(:call, nil, :f),
|
1640
|
+
s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c"))
|
1641
|
+
|
1642
|
+
assert_parse rb, pt
|
1643
|
+
end
|
1644
|
+
|
1645
|
+
def test_iter_args_10_2
|
1646
|
+
rb = "f { |a, b = 42, *c, &d| }"
|
1647
|
+
pt = s(:iter, s(:call, nil, :f),
|
1648
|
+
s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :"&d"))
|
1649
|
+
|
1650
|
+
assert_parse rb, pt
|
1651
|
+
end
|
1652
|
+
|
1653
|
+
def test_iter_args_11_1
|
1654
|
+
rb = "f { |a, b = 42, *c, d| }"
|
1655
|
+
pt = s(:iter, s(:call, nil, :f),
|
1656
|
+
s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d))
|
1657
|
+
|
1658
|
+
assert_parse rb, pt
|
1659
|
+
end
|
1660
|
+
|
1661
|
+
def test_iter_args_11_2
|
1662
|
+
rb = "f { |a, b = 42, *c, d, &e| }"
|
1663
|
+
pt = s(:iter, s(:call, nil, :f),
|
1664
|
+
s(:args, :a, s(:lasgn, :b, s(:lit, 42)), :"*c", :d, :"&e"))
|
1665
|
+
|
1666
|
+
assert_parse rb, pt
|
1667
|
+
end
|
1668
|
+
|
1669
|
+
def test_kill_me_6
|
1670
|
+
# | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
|
1671
|
+
rb = "f { |a, (b, *c, d)| }"
|
1672
|
+
pt = s(:iter,
|
1673
|
+
s(:call, nil, :f),
|
1674
|
+
s(:args, :a, s(:masgn, :b, :"*c", :d)))
|
1675
|
+
|
1676
|
+
assert_parse rb, pt
|
1677
|
+
end
|
1678
|
+
|
1679
|
+
def test_kill_me_7
|
1680
|
+
# | f_marg_list tCOMMA tSTAR
|
1681
|
+
rb = "f { |a, (b, *)| }"
|
1682
|
+
pt = s(:iter,
|
1683
|
+
s(:call, nil, :f),
|
1684
|
+
s(:args, :a, s(:masgn, :b, :*)))
|
1685
|
+
|
1686
|
+
assert_parse rb, pt
|
1687
|
+
end
|
1688
|
+
|
1689
|
+
def test_kill_me_8
|
1690
|
+
# | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
|
1691
|
+
rb = "f { |a, (b, *, c)| }"
|
1692
|
+
pt = s(:iter,
|
1693
|
+
s(:call, nil, :f),
|
1694
|
+
s(:args, :a, s(:masgn, :b, :*, :c)))
|
1695
|
+
|
1696
|
+
assert_parse rb, pt
|
1697
|
+
end
|
1698
|
+
|
1699
|
+
def test_kill_me_9
|
1700
|
+
# | tSTAR f_norm_arg
|
1701
|
+
rb = "f { |a, (*b)| }"
|
1702
|
+
pt = s(:iter,
|
1703
|
+
s(:call, nil, :f),
|
1704
|
+
s(:args, :a, s(:masgn, :"*b")))
|
1705
|
+
|
1706
|
+
assert_parse rb, pt
|
1707
|
+
end
|
1708
|
+
|
1709
|
+
def test_kill_me_10
|
1710
|
+
# | tSTAR f_norm_arg tCOMMA f_marg_list
|
1711
|
+
rb = "f { |a, (*b, c)| }"
|
1712
|
+
pt = s(:iter,
|
1713
|
+
s(:call, nil, :f),
|
1714
|
+
s(:args, :a, s(:masgn, :"*b", :c)))
|
1715
|
+
|
1716
|
+
assert_parse rb, pt
|
1717
|
+
end
|
1718
|
+
|
1719
|
+
def test_kill_me_11
|
1720
|
+
# | tSTAR
|
1721
|
+
rb = "f { |a, (*)| }"
|
1722
|
+
pt = s(:iter,
|
1723
|
+
s(:call, nil, :f),
|
1724
|
+
s(:args, :a, s(:masgn, :*)))
|
1725
|
+
|
1726
|
+
assert_parse rb, pt
|
1727
|
+
end
|
1728
|
+
|
1729
|
+
def test_kill_me_12
|
1730
|
+
# | tSTAR tCOMMA f_marg_list
|
1731
|
+
rb = "f { |a, (*, b)| }"
|
1732
|
+
pt = s(:iter,
|
1733
|
+
s(:call, nil, :f),
|
1734
|
+
s(:args, :a, s(:masgn, :*, :b)))
|
1735
|
+
|
1736
|
+
assert_parse rb, pt
|
1737
|
+
end
|
1738
|
+
|
1739
|
+
def test_index_0
|
1740
|
+
rb = "a[] = b"
|
1741
|
+
pt = s(:attrasgn, s(:call, nil, :a), :[]=, s(:call, nil, :b))
|
1742
|
+
|
1743
|
+
assert_parse rb, pt
|
1744
|
+
end
|
1745
|
+
|
1746
|
+
def test_lambda_do_vs_brace
|
1747
|
+
pt = s(:call, nil, :f, s(:iter, s(:call, nil, :lambda), 0))
|
1748
|
+
|
1749
|
+
rb = "f ->() {}"
|
1750
|
+
assert_parse rb, pt
|
1751
|
+
|
1752
|
+
rb = "f ->() do end"
|
1753
|
+
assert_parse rb, pt
|
1754
|
+
end
|
1755
|
+
|
1756
|
+
def test_thingy
|
1757
|
+
pt = s(:call, s(:call, nil, :f), :call, s(:lit, 42))
|
1758
|
+
|
1759
|
+
rb = "f.(42)"
|
1760
|
+
assert_parse rb, pt
|
1761
|
+
|
1762
|
+
rb = "f::(42)"
|
1763
|
+
assert_parse rb, pt
|
1764
|
+
end
|
1765
|
+
|
1766
|
+
def test_unary_plus_on_literal
|
1767
|
+
rb = "+:a"
|
1768
|
+
pt = s(:call, s(:lit, :a), :+@)
|
1769
|
+
|
1770
|
+
assert_parse rb, pt
|
1771
|
+
end
|
1772
|
+
end
|