ruby_parser 1.0.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.
Potentially problematic release.
This version of ruby_parser might be problematic. Click here for more details.
- data/.autotest +21 -0
- data/History.txt +5 -0
- data/Manifest.txt +9 -0
- data/README.txt +64 -0
- data/Rakefile +56 -0
- data/lib/ruby_lexer.rb +2751 -0
- data/lib/ruby_parser.rb +5987 -0
- data/lib/ruby_parser.y +1648 -0
- data/test/test_ruby_lexer.rb +398 -0
- data/test/test_ruby_parser.rb +326 -0
- metadata +83 -0
@@ -0,0 +1,398 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ruby_lexer'
|
5
|
+
|
6
|
+
class TestRubyLexer < Test::Unit::TestCase
|
7
|
+
def deny cond, msg = nil
|
8
|
+
assert ! cond, msg
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@lex = RubyLexer.new
|
13
|
+
@lex.src = StringIO.new("blah blah")
|
14
|
+
@lex.lex_state = :expr_beg # HACK ? I have no idea actually
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_advance
|
18
|
+
assert @lex.advance # blah
|
19
|
+
assert @lex.advance # blah
|
20
|
+
deny @lex.advance # nada
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_is_next_identchar
|
24
|
+
assert @lex.is_next_identchar
|
25
|
+
@lex.src = StringIO.new(" ")
|
26
|
+
deny @lex.is_next_identchar
|
27
|
+
@lex.src = StringIO.new("-")
|
28
|
+
deny @lex.is_next_identchar
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_is_next_no_case # TODO: worst name evah
|
32
|
+
@lex.src = StringIO.new("123 456")
|
33
|
+
assert @lex.is_next_no_case("123")
|
34
|
+
pos = @lex.src.pos
|
35
|
+
deny @lex.is_next_no_case("begin")
|
36
|
+
assert_equal " 456", @lex.src.read_all, "must put back contents"
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_number_token
|
40
|
+
node = @lex.number_token("42", false, "\0")
|
41
|
+
assert_equal :tINTEGER, node
|
42
|
+
assert_equal 42, @lex.yacc_value
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_parse_number
|
46
|
+
@lex.src = StringIO.new '42'
|
47
|
+
node = @lex.parse_number('1')
|
48
|
+
assert_equal :tINTEGER, node
|
49
|
+
assert_equal 142, @lex.yacc_value
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_parse_quote
|
53
|
+
@lex.src = StringIO.new 'blah)'
|
54
|
+
node = @lex.parse_quote('(')
|
55
|
+
assert_equal :tSTRING_BEG, node
|
56
|
+
assert_equal s(:strterm, RubyLexer::STR_DQUOTE, ")", "("), @lex.lex_strterm
|
57
|
+
assert_equal ["%)"], @lex.yacc_value.args # FIX double check this
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_yylex_integer
|
61
|
+
util_lex_token "42", :tINTEGER, 42
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_yylex_integer_eh_a
|
65
|
+
util_lex_token('?a',
|
66
|
+
:tINTEGER, 97)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_yylex_integer_eh_escape_M_escape_C
|
70
|
+
util_lex_token('?\M-\C-a',
|
71
|
+
:tINTEGER, 129)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_yylex_float
|
75
|
+
util_lex_token "1.0", :tFLOAT, 1.0
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_yylex_constant
|
79
|
+
util_lex_token("ArgumentError",
|
80
|
+
:tCONSTANT, t("ArgumentError"))
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_yylex_constant_semi
|
84
|
+
util_lex_token("ArgumentError;",
|
85
|
+
:tCONSTANT, t("ArgumentError"),
|
86
|
+
";", t(";"))
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_yylex_identifier
|
90
|
+
util_lex_token("identifier",
|
91
|
+
:tIDENTIFIER, t("identifier"))
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_yylex_regexp
|
95
|
+
util_lex_token("/regexp/",
|
96
|
+
:tREGEXP_BEG, t("/"),
|
97
|
+
:tSTRING_CONTENT, s(:str, "regexp"),
|
98
|
+
:tREGEXP_END, "")
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_yylex_regexp_nm
|
102
|
+
util_lex_token("/.*/nm",
|
103
|
+
:tREGEXP_BEG, t("/"),
|
104
|
+
:tSTRING_CONTENT, s(:str, ".*"),
|
105
|
+
:tREGEXP_END, "nm")
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_yylex_regexp_escapes
|
109
|
+
util_lex_token('/re\tge\nxp/',
|
110
|
+
:tREGEXP_BEG, t("/"),
|
111
|
+
:tSTRING_CONTENT, s(:str, "re\\tge\\nxp"),
|
112
|
+
:tREGEXP_END, "")
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_yylex_regexp_escape_oct
|
116
|
+
util_lex_token('/re\tge\101xp/',
|
117
|
+
:tREGEXP_BEG, t("/"),
|
118
|
+
:tSTRING_CONTENT, s(:str, "re\\tge\\101xp"),
|
119
|
+
:tREGEXP_END, "")
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_yylex_regexp_escape_hex
|
123
|
+
util_lex_token('/re\tge\x61xp/',
|
124
|
+
:tREGEXP_BEG, t("/"),
|
125
|
+
:tSTRING_CONTENT, s(:str, "re\\tge\\x61xp"),
|
126
|
+
:tREGEXP_END, "")
|
127
|
+
end
|
128
|
+
|
129
|
+
def test_yylex_string_double
|
130
|
+
util_lex_token('"string"',
|
131
|
+
:tSTRING_BEG, t('"'),
|
132
|
+
:tSTRING_CONTENT, s(:str, "string"),
|
133
|
+
:tSTRING_END, t('"'))
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_yylex_string_double_escapes
|
137
|
+
util_lex_token('"s\tri\ng"',
|
138
|
+
:tSTRING_BEG, t('"'),
|
139
|
+
:tSTRING_CONTENT, s(:str, "s\tri\ng"),
|
140
|
+
:tSTRING_END, t('"'))
|
141
|
+
end
|
142
|
+
|
143
|
+
def test_yylex_string_double_escape_M
|
144
|
+
util_lex_token('"\M-g"',
|
145
|
+
:tSTRING_BEG, t('"'),
|
146
|
+
:tSTRING_CONTENT, s(:str, "\347"),
|
147
|
+
:tSTRING_END, t('"'))
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_yylex_string_double_escape_octal
|
151
|
+
util_lex_token('"n = \101\102\103"',
|
152
|
+
:tSTRING_BEG, t('"'),
|
153
|
+
:tSTRING_CONTENT, s(:str, "n = ABC"),
|
154
|
+
:tSTRING_END, t('"'))
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_yylex_string_double_escape_hex
|
158
|
+
util_lex_token('"n = \x61\x62\x63"',
|
159
|
+
:tSTRING_BEG, t('"'),
|
160
|
+
:tSTRING_CONTENT, s(:str, "n = abc"),
|
161
|
+
:tSTRING_END, t('"'))
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_yylex_string_single
|
165
|
+
util_lex_token("'string'",
|
166
|
+
:tSTRING_BEG, t("'"),
|
167
|
+
:tSTRING_CONTENT, s(:str, "string"),
|
168
|
+
:tSTRING_END, t("'"))
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_yylex_string_pct_Q
|
172
|
+
util_lex_token("%Q[string]",
|
173
|
+
:tSTRING_BEG, t("%Q["),
|
174
|
+
:tSTRING_CONTENT, s(:str, "string"),
|
175
|
+
:tSTRING_END, t("]"))
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_yylex_string_single_escapes
|
179
|
+
util_lex_token("'s\\tri\\ng'",
|
180
|
+
:tSTRING_BEG, t("'"),
|
181
|
+
:tSTRING_CONTENT, s(:str, "s\\tri\\ng"),
|
182
|
+
:tSTRING_END, t("'"))
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_yylex_global
|
186
|
+
util_lex_token("$blah",
|
187
|
+
:tGVAR, t("$blah"))
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_yylex_global_wierd
|
191
|
+
util_lex_token("$__blah",
|
192
|
+
:tGVAR, t("$__blah"))
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_yylex_global_dollar_underscore
|
196
|
+
util_lex_token("$_",
|
197
|
+
:tGVAR, t("$_"))
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_yylex_symbol
|
201
|
+
util_lex_token(":symbol",
|
202
|
+
:tSYMBEG, t(":"),
|
203
|
+
:tIDENTIFIER, t("symbol"))
|
204
|
+
end
|
205
|
+
|
206
|
+
def test_yylex_comment_begin
|
207
|
+
util_lex_token("=begin\nblah\nblah\n=end\n42",
|
208
|
+
:tINTEGER, 42)
|
209
|
+
end
|
210
|
+
|
211
|
+
def util_lex_token input, *args
|
212
|
+
@lex.src = StringIO.new input
|
213
|
+
|
214
|
+
until args.empty? do
|
215
|
+
token = args.shift
|
216
|
+
value = args.shift
|
217
|
+
assert @lex.advance, "no more tokens"
|
218
|
+
assert_equal [token, value], [@lex.token, @lex.yacc_value]
|
219
|
+
end
|
220
|
+
|
221
|
+
deny @lex.advance, "must be empty, but had #{[@lex.token, @lex.yacc_value].inspect}"
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
class TestStackState < Test::Unit::TestCase
|
226
|
+
def test_stack_state
|
227
|
+
s = StackState.new :test
|
228
|
+
s.push true
|
229
|
+
s.push false
|
230
|
+
s.lexpop
|
231
|
+
assert_equal [false, true], s.stack
|
232
|
+
end
|
233
|
+
|
234
|
+
def test_is_in_state
|
235
|
+
s = StackState.new :test
|
236
|
+
assert_equal false, s.is_in_state
|
237
|
+
s.push false
|
238
|
+
assert_equal false, s.is_in_state
|
239
|
+
s.push true
|
240
|
+
assert_equal true, s.is_in_state
|
241
|
+
s.push false
|
242
|
+
assert_equal false, s.is_in_state
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_lexpop
|
246
|
+
s = StackState.new :test
|
247
|
+
assert_equal [false], s.stack
|
248
|
+
s.push true
|
249
|
+
s.push false
|
250
|
+
assert_equal [false, true, false], s.stack
|
251
|
+
s.lexpop
|
252
|
+
assert_equal [false, true], s.stack
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_pop
|
256
|
+
s = StackState.new :test
|
257
|
+
assert_equal [false], s.stack
|
258
|
+
s.push true
|
259
|
+
assert_equal [false, true], s.stack
|
260
|
+
assert_equal true, s.pop
|
261
|
+
assert_equal [false], s.stack
|
262
|
+
end
|
263
|
+
|
264
|
+
def test_push
|
265
|
+
s = StackState.new :test
|
266
|
+
assert_equal [false], s.stack
|
267
|
+
s.push true
|
268
|
+
s.push false
|
269
|
+
assert_equal [false, true, false], s.stack
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
class TestEnvironment < Test::Unit::TestCase
|
274
|
+
def deny t
|
275
|
+
assert ! t
|
276
|
+
end
|
277
|
+
|
278
|
+
def setup
|
279
|
+
@env = Environment.new
|
280
|
+
@env[:blah] = 42
|
281
|
+
assert_equal 42, @env[:blah]
|
282
|
+
end
|
283
|
+
|
284
|
+
def test_use
|
285
|
+
@env.use :blah
|
286
|
+
expected = [{ :blah => true }]
|
287
|
+
assert_equal expected, @env.instance_variable_get(:"@use")
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_use_scoped
|
291
|
+
@env.use :blah
|
292
|
+
@env.extend
|
293
|
+
expected = [{}, { :blah => true }]
|
294
|
+
assert_equal expected, @env.instance_variable_get(:"@use")
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_used_eh
|
298
|
+
@env.extend :dynamic
|
299
|
+
@env[:x] = :dvar
|
300
|
+
@env.use :x
|
301
|
+
assert_equal true, @env.used?(:x)
|
302
|
+
end
|
303
|
+
|
304
|
+
def test_used_eh_none
|
305
|
+
assert_equal nil, @env.used?(:x)
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_used_eh_scoped
|
309
|
+
self.test_used_eh
|
310
|
+
@env.extend :dynamic
|
311
|
+
assert_equal true, @env.used?(:x)
|
312
|
+
end
|
313
|
+
|
314
|
+
def test_var_scope_dynamic
|
315
|
+
@env.extend :dynamic
|
316
|
+
assert_equal 42, @env[:blah]
|
317
|
+
@env.unextend
|
318
|
+
assert_equal 42, @env[:blah]
|
319
|
+
end
|
320
|
+
|
321
|
+
def test_var_scope_static
|
322
|
+
@env.extend
|
323
|
+
assert_equal nil, @env[:blah]
|
324
|
+
@env.unextend
|
325
|
+
assert_equal 42, @env[:blah]
|
326
|
+
end
|
327
|
+
|
328
|
+
def test_dynamic
|
329
|
+
expected1 = {}
|
330
|
+
expected2 = { :x => 42 }
|
331
|
+
|
332
|
+
assert_equal expected1, @env.dynamic
|
333
|
+
begin
|
334
|
+
@env.extend :dynamic
|
335
|
+
assert_equal expected1, @env.dynamic
|
336
|
+
|
337
|
+
@env[:x] = 42
|
338
|
+
assert_equal expected2, @env.dynamic
|
339
|
+
|
340
|
+
begin
|
341
|
+
@env.extend :dynamic
|
342
|
+
assert_equal expected2, @env.dynamic
|
343
|
+
@env.unextend
|
344
|
+
end
|
345
|
+
|
346
|
+
assert_equal expected2, @env.dynamic
|
347
|
+
@env.unextend
|
348
|
+
end
|
349
|
+
assert_equal expected1, @env.dynamic
|
350
|
+
end
|
351
|
+
|
352
|
+
def test_all_dynamic
|
353
|
+
expected = { :blah => 42 }
|
354
|
+
|
355
|
+
@env.extend :dynamic
|
356
|
+
assert_equal expected, @env.all
|
357
|
+
@env.unextend
|
358
|
+
assert_equal expected, @env.all
|
359
|
+
end
|
360
|
+
|
361
|
+
def test_all_static
|
362
|
+
@env.extend
|
363
|
+
expected = { }
|
364
|
+
assert_equal expected, @env.all
|
365
|
+
|
366
|
+
@env.unextend
|
367
|
+
expected = { :blah => 42 }
|
368
|
+
assert_equal expected, @env.all
|
369
|
+
end
|
370
|
+
|
371
|
+
def test_dynamic_eh
|
372
|
+
assert_equal false, @env.dynamic?
|
373
|
+
@env.extend :dynamic
|
374
|
+
assert_equal true, @env.dynamic?
|
375
|
+
@env.extend
|
376
|
+
assert_equal false, @env.dynamic?
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_all_static_deeper
|
380
|
+
expected0 = { :blah => 42 }
|
381
|
+
expected1 = { :blah => 42, :blah2 => 24 }
|
382
|
+
expected2 = { :blah => 27 }
|
383
|
+
|
384
|
+
@env.extend :dynamic
|
385
|
+
@env[:blah2] = 24
|
386
|
+
assert_equal expected1, @env.all
|
387
|
+
|
388
|
+
@env.extend
|
389
|
+
@env[:blah] = 27
|
390
|
+
assert_equal expected2, @env.all
|
391
|
+
|
392
|
+
@env.unextend
|
393
|
+
assert_equal expected1, @env.all
|
394
|
+
|
395
|
+
@env.unextend
|
396
|
+
assert_equal expected0, @env.all
|
397
|
+
end
|
398
|
+
end
|
@@ -0,0 +1,326 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ruby_parser'
|
5
|
+
|
6
|
+
$: << File.expand_path('~/Work/p4/zss/src/ParseTree/dev/lib')
|
7
|
+
$: << File.expand_path('~/Work/p4/zss/src/ParseTree/dev/test')
|
8
|
+
|
9
|
+
require 'pt_testcase'
|
10
|
+
|
11
|
+
class TestRubyParser < Test::Unit::TestCase # ParseTreeTestCase
|
12
|
+
|
13
|
+
# Regular ParseTreeTestCase tests
|
14
|
+
eval ParseTreeTestCase.testcases.map { |node, data|
|
15
|
+
next if node.to_s =~ /bmethod|dmethod/
|
16
|
+
next if Array === data['Ruby'] # runtime only crap
|
17
|
+
"def test_#{node}
|
18
|
+
rb = #{data['Ruby'].inspect}
|
19
|
+
pt = #{data['ParseTree'].inspect}
|
20
|
+
|
21
|
+
assert_not_nil rb, \"Ruby for #{node} undefined\"
|
22
|
+
assert_not_nil pt, \"ParseTree for #{node} undefined\"
|
23
|
+
|
24
|
+
assert_equal Sexp.from_array(pt), @processor.parse(rb)
|
25
|
+
end"
|
26
|
+
}.compact.join("\n")
|
27
|
+
|
28
|
+
# Scour the world and compare against ParseTree
|
29
|
+
if ENV['ZOMGPONIES'] or File.exist? 'zomgponies' then
|
30
|
+
require 'parse_tree'
|
31
|
+
|
32
|
+
base = "/usr/lib/ruby"
|
33
|
+
base = "unit"
|
34
|
+
|
35
|
+
files = Dir[File.join(base, "**/*.rb")]
|
36
|
+
|
37
|
+
# these files/patterns cause parse_tree_show to bus error (or just suck):
|
38
|
+
files.reject! { |f| f =~ /environments.environment|rss.maker.base|rails_generator|ferret.browser|rubinius.spec.core.module.(constants|name|remove_const)_spec|tkextlib.tcllib.tablelist/ }
|
39
|
+
|
40
|
+
# these are rejected for dasgn_curr ordering failures... I'll fix them later.
|
41
|
+
# (or mri parse errors--I should have separated them out)
|
42
|
+
files.reject! { |f| f =~ /lib.flog|lib.autotest.notify|lib.analyzer.tools.rails.stat|flog.lib.flog|rakelib.struct.generator|rubinius.kernel.core.array|lib.rbosa.rb|src.rbosa.rb|spec.spec.mocks.mock.spec.rb|dsl.shared.behaviour.spec.rb|spec.spec.dsl.behaviour.spec|lib.hpricot.parse.rb|resolve.rb|parsers.parse.f95|rubinius.shotgun.lib.primitives.ltm|rubinius.lib.bin.compile|rubinius.kernel.core.object|rubinius.kernel.core.file|rubinius.compiler2.garnet.bindingagent|ruby_to_c_test_r2ctestcase|lib.more.like.this|resolv\.rb|test.r2ctestcase/ }
|
43
|
+
|
44
|
+
warn "Generating #{files.size} tests from #{base}"
|
45
|
+
|
46
|
+
eval files.map { |file|
|
47
|
+
name = file[base.size..-1].gsub(/\W+/, '_')
|
48
|
+
|
49
|
+
loc = `wc -l #{file}`.strip.to_i
|
50
|
+
|
51
|
+
"def test#{name}_#{loc}
|
52
|
+
file = #{file.inspect}
|
53
|
+
rb = File.read(file)
|
54
|
+
|
55
|
+
pt = ParseTree.new.parse_tree_for_string rb
|
56
|
+
assert_not_nil pt, \"ParseTree for #{name} undefined\"
|
57
|
+
|
58
|
+
rp = @processor.parse rb
|
59
|
+
assert_equal Sexp.from_array(pt).first, rp, \"RP different from PT\"
|
60
|
+
File.unlink #{file.inspect}
|
61
|
+
end"
|
62
|
+
}.compact.join("\n")
|
63
|
+
end
|
64
|
+
|
65
|
+
def setup
|
66
|
+
super
|
67
|
+
|
68
|
+
# puts self.name
|
69
|
+
|
70
|
+
@processor = RubyParser.new
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_block_append
|
74
|
+
head = s(:args)
|
75
|
+
tail = s(:zsuper)
|
76
|
+
expected = s(:block, s(:args), s(:zsuper))
|
77
|
+
assert_equal expected, @processor.block_append(head, tail)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_block_append_block
|
81
|
+
head = s(:block, s(:args))
|
82
|
+
tail = s(:zsuper)
|
83
|
+
expected = s(:block, s(:args), s(:zsuper))
|
84
|
+
assert_equal expected, @processor.block_append(head, tail)
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_block_append_tail_block
|
88
|
+
head = s(:vcall, :f1)
|
89
|
+
tail = s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y)))
|
90
|
+
expected = s(:block,
|
91
|
+
s(:vcall, :f1),
|
92
|
+
s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y))))
|
93
|
+
assert_equal expected, @processor.block_append(head, tail)
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_block_append_begin_begin
|
97
|
+
head = s(:begin, s(:args))
|
98
|
+
tail = s(:begin, s(:args))
|
99
|
+
expected = s(:block, s(:args), s(:begin, s(:args)))
|
100
|
+
assert_equal expected, @processor.block_append(head, tail)
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_block_append_nil_head
|
104
|
+
head = nil
|
105
|
+
tail = s(:zsuper)
|
106
|
+
expected = s(:zsuper)
|
107
|
+
assert_equal expected, @processor.block_append(head, tail)
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_block_append_nil_tail
|
111
|
+
head = s(:args)
|
112
|
+
tail = nil
|
113
|
+
expected = s(:args)
|
114
|
+
assert_equal expected, @processor.block_append(head, tail)
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_call_env
|
118
|
+
@processor.env[:a] = :lvar
|
119
|
+
expected = s(:call, s(:lvar, :a), :happy)
|
120
|
+
|
121
|
+
assert_equal expected, @processor.parse('a.happy')
|
122
|
+
end
|
123
|
+
|
124
|
+
def test_do_bug # TODO: rename
|
125
|
+
rb = "a 1\na.b do |c|\n # do nothing\nend"
|
126
|
+
pt = s(:block,
|
127
|
+
s(:fcall, :a, s(:array, s(:lit, 1))),
|
128
|
+
s(:iter, s(:call, s(:vcall, :a), :b), s(:dasgn_curr, :c)))
|
129
|
+
|
130
|
+
assert_equal pt, @processor.parse(rb)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_lasgn_env
|
134
|
+
rb = 'a = 42'
|
135
|
+
pt = s(:lasgn, :a, s(:lit, 42))
|
136
|
+
expected_env = { :a => :lvar }
|
137
|
+
|
138
|
+
assert_equal pt, @processor.parse(rb)
|
139
|
+
assert_equal expected_env, @processor.env.all
|
140
|
+
end
|
141
|
+
|
142
|
+
def test_logop_12
|
143
|
+
lhs = s(:lit, 1)
|
144
|
+
rhs = s(:lit, 2)
|
145
|
+
exp = s(:and, s(:lit, 1), s(:lit, 2))
|
146
|
+
|
147
|
+
assert_equal exp, @processor.logop(:and, lhs, rhs)
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_logop_12_3
|
151
|
+
lhs = s(:and, s(:lit, 1), s(:lit, 2))
|
152
|
+
rhs = s(:lit, 3)
|
153
|
+
exp = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
|
154
|
+
|
155
|
+
assert_equal exp, @processor.logop(:and, lhs, rhs)
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_logop_123_4
|
159
|
+
lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:lit, 3)))
|
160
|
+
rhs = s(:lit, 4)
|
161
|
+
exp = s(:and,
|
162
|
+
s(:lit, 1),
|
163
|
+
s(:and,
|
164
|
+
s(:lit, 2),
|
165
|
+
s(:and,
|
166
|
+
s(:lit, 3),
|
167
|
+
s(:lit, 4))))
|
168
|
+
|
169
|
+
assert_equal exp, @processor.logop(:and, lhs, rhs)
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_logop_1234_5
|
173
|
+
lhs = s(:and, s(:lit, 1), s(:and, s(:lit, 2), s(:and, s(:lit, 3), s(:lit, 4))))
|
174
|
+
rhs = s(:lit, 5)
|
175
|
+
exp = s(:and,
|
176
|
+
s(:lit, 1),
|
177
|
+
s(:and,
|
178
|
+
s(:lit, 2),
|
179
|
+
s(:and,
|
180
|
+
s(:lit, 3),
|
181
|
+
s(:and,
|
182
|
+
s(:lit, 4),
|
183
|
+
s(:lit, 5)))))
|
184
|
+
|
185
|
+
assert_equal exp, @processor.logop(:and, lhs, rhs)
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_logop_nested_mix
|
189
|
+
lhs = s(:or, s(:vcall, :a), s(:vcall, :b))
|
190
|
+
rhs = s(:and, s(:vcall, :c), s(:vcall, :d))
|
191
|
+
exp = s(:or,
|
192
|
+
s(:or, s(:vcall, :a), s(:vcall, :b)),
|
193
|
+
s(:and, s(:vcall, :c), s(:vcall, :d)))
|
194
|
+
|
195
|
+
lhs.paren = true
|
196
|
+
rhs.paren = true
|
197
|
+
|
198
|
+
assert_equal exp, @processor.logop(:or, lhs, rhs)
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_literal_concat_str_evstr
|
202
|
+
lhs, rhs = s(:str, ""), s(:evstr, s(:str, "blah"))
|
203
|
+
|
204
|
+
assert_equal s(:str, "blah"), @processor.literal_concat(lhs, rhs)
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_literal_concat_evstr_evstr
|
208
|
+
lhs, rhs = s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2))
|
209
|
+
expected = s(:dstr, "", s(:evstr, s(:lit, 1)), s(:evstr, s(:lit, 2)))
|
210
|
+
|
211
|
+
assert_equal expected, @processor.literal_concat(lhs, rhs)
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_literal_concat_dstr_evstr
|
215
|
+
lhs, rhs = s(:dstr, "a"), s(:evstr, s(:vcall, :b))
|
216
|
+
expected = s(:dstr, "a", s(:evstr, s(:vcall, :b)))
|
217
|
+
|
218
|
+
assert_equal expected, @processor.literal_concat(lhs, rhs)
|
219
|
+
end
|
220
|
+
|
221
|
+
def test_literal_concat_dstr_dstr
|
222
|
+
lhs = s(:dstr, "Failed to download spec ",
|
223
|
+
s(:evstr, s(:vcall, :spec_name)),
|
224
|
+
s(:str, " from "),
|
225
|
+
s(:evstr, s(:vcall, :source_uri)),
|
226
|
+
s(:str, ":\n"))
|
227
|
+
rhs = s(:dstr, "\t",
|
228
|
+
s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
|
229
|
+
expected = s(:dstr, "Failed to download spec ",
|
230
|
+
s(:evstr, s(:vcall, :spec_name)),
|
231
|
+
s(:str, " from "),
|
232
|
+
s(:evstr, s(:vcall, :source_uri)),
|
233
|
+
s(:str, ":\n"),
|
234
|
+
s(:str, "\t"),
|
235
|
+
s(:evstr, s(:call, s(:ivar, :@fetch_error), :message)))
|
236
|
+
|
237
|
+
assert_equal expected, @processor.literal_concat(lhs, rhs)
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_str_pct_Q_nested
|
241
|
+
rb = "%Q[before [#\{nest}] after]"
|
242
|
+
pt = s(:dstr, "before [", s(:evstr, s(:vcall, :nest)), s(:str, "] after"))
|
243
|
+
|
244
|
+
assert_equal pt, @processor.parse(rb)
|
245
|
+
end
|
246
|
+
|
247
|
+
def test_str_str
|
248
|
+
rb = "\"a #\{'b'}\""
|
249
|
+
pt = s(:str, "a b")
|
250
|
+
|
251
|
+
assert_equal pt, @processor.parse(rb)
|
252
|
+
end
|
253
|
+
|
254
|
+
def test_str_str_str
|
255
|
+
rb = "\"a #\{'b'} c\""
|
256
|
+
pt = s(:str, "a b c")
|
257
|
+
|
258
|
+
assert_equal pt, @processor.parse(rb)
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_dstr_str
|
262
|
+
rb = "\"#\{'a'} b\""
|
263
|
+
pt = s(:str, "a b")
|
264
|
+
|
265
|
+
assert_equal pt, @processor.parse(rb)
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_str_evstr
|
269
|
+
rb = "\"a #\{b}\""
|
270
|
+
pt = s(:dstr, "a ", s(:evstr, s(:vcall, :b)))
|
271
|
+
|
272
|
+
assert_equal pt, @processor.parse(rb)
|
273
|
+
end
|
274
|
+
|
275
|
+
def test_dstr_evstr
|
276
|
+
rb = "\"#\{'a'}#\{b}\""
|
277
|
+
pt = s(:dstr, "a", s(:evstr, s(:vcall, :b)))
|
278
|
+
|
279
|
+
assert_equal pt, @processor.parse(rb)
|
280
|
+
end
|
281
|
+
|
282
|
+
def test_evstr_str
|
283
|
+
rb = "\"#\{a} b\""
|
284
|
+
pt = s(:dstr, "", s(:evstr, s(:vcall, :a)), s(:str, " b"))
|
285
|
+
|
286
|
+
assert_equal pt, @processor.parse(rb)
|
287
|
+
end
|
288
|
+
|
289
|
+
def test_evstr_evstr
|
290
|
+
rb = "\"#\{a}#\{b}\""
|
291
|
+
pt = s(:dstr, "", s(:evstr, s(:vcall, :a)), s(:evstr, s(:vcall, :b)))
|
292
|
+
|
293
|
+
assert_equal pt, @processor.parse(rb)
|
294
|
+
end
|
295
|
+
|
296
|
+
|
297
|
+
def test_dasgn_icky2
|
298
|
+
rb = "a do\n v = nil\n begin\n yield\n rescue Exception => v\n break\n end\nend"
|
299
|
+
pt = s(:iter,
|
300
|
+
s(:fcall, :a),
|
301
|
+
nil,
|
302
|
+
s(:block,
|
303
|
+
s(:dasgn_curr, :v, s(:nil)),
|
304
|
+
s(:begin,
|
305
|
+
s(:rescue,
|
306
|
+
s(:yield),
|
307
|
+
s(:resbody,
|
308
|
+
s(:array, s(:const, :Exception)),
|
309
|
+
s(:block, s(:dasgn_curr, :v, s(:gvar, :$!)), s(:break)))))))
|
310
|
+
|
311
|
+
assert_equal pt, @processor.parse(rb)
|
312
|
+
end
|
313
|
+
|
314
|
+
def test_list_append
|
315
|
+
lhs, rhs = s(:array, s(:lit, :iter)), s(:when, s(:const, :BRANCHING), nil)
|
316
|
+
expected = s(:array, s(:lit, :iter), s(:when, s(:const, :BRANCHING), nil))
|
317
|
+
|
318
|
+
assert_equal expected, @processor.list_append(lhs, rhs)
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
__END__
|
323
|
+
|
324
|
+
# blah18.rb
|
325
|
+
|
326
|
+
assert_equal("sub", $_)
|