PageRenderTime 56ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/Languages/Ruby/Tests/Libraries/ParseTreeTests/pt_testcase.rb

http://github.com/IronLanguages/main
Ruby | 4417 lines | 4031 code | 367 blank | 19 comment | 50 complexity | 0dabc318eca4f3b643847b08c718de70 MD5 | raw file
Possible License(s): CPL-1.0, BSD-3-Clause, ISC, GPL-2.0, MPL-2.0-no-copyleft-exception

Large files files are truncated, but you can click here to view the full file

  1. $TESTING = true
  2. require 'minitest/unit'
  3. require 'sexp_processor' # for deep_clone
  4. # key:
  5. # wwtt = what were they thinking?
  6. # TODO: <ko1_> 1.8.7 support {|&b|} syntax
  7. class Examples
  8. attr_reader :reader
  9. attr_writer :writer
  10. def a_method(x); x+1; end
  11. alias an_alias a_method
  12. define_method(:bmethod_noargs) do
  13. x + 1
  14. end
  15. define_method(:unsplatted) do |x|
  16. x + 1
  17. end
  18. define_method :splatted do |*args|
  19. y = args.first
  20. y + 42
  21. end
  22. define_method :dmethod_added, instance_method(:a_method) if
  23. RUBY_VERSION < "1.9"
  24. end
  25. class ParseTreeTestCase < MiniTest::Unit::TestCase
  26. attr_accessor :processor # to be defined by subclass
  27. def setup
  28. super
  29. @processor = nil
  30. end
  31. def after_process_hook klass, node, data, input_name, output_name
  32. end
  33. def before_process_hook klass, node, data, input_name, output_name
  34. end
  35. def self.add_test name, data, klass = self.name[4..-1]
  36. name = name.to_s
  37. klass = klass.to_s
  38. if testcases.has_key? name then
  39. if testcases[name].has_key? klass then
  40. warn "testcase #{klass}##{name} already has data"
  41. else
  42. testcases[name][klass] = data
  43. end
  44. else
  45. warn "testcase #{name} does not exist"
  46. end
  47. end
  48. def self.add_tests name, hash
  49. name = name.to_s
  50. hash.each do |klass, data|
  51. warn "testcase #{klass}##{name} already has data" if
  52. testcases[name].has_key? klass
  53. testcases[name][klass] = data
  54. end
  55. end
  56. def self.clone_same
  57. @@testcases.each do |node, data|
  58. data.each do |key, val|
  59. if val == :same then
  60. prev_key = self.previous(key)
  61. data[key] = data[prev_key].deep_clone
  62. end
  63. end
  64. end
  65. end
  66. def self.copy_test_case nonverbose, klass
  67. verbose = nonverbose + "_mri_verbose_flag"
  68. testcases[verbose][klass] = testcases[nonverbose][klass]
  69. end
  70. def self.generate_test klass, node, data, input_name, output_name
  71. klass.send(:define_method, "test_#{node}".to_sym) do
  72. flunk "Processor is nil" if processor.nil?
  73. assert data.has_key?(input_name), "Unknown input data"
  74. assert data.has_key?(output_name), "Missing test data"
  75. $missing[node] << output_name unless data.has_key? output_name
  76. input = data[input_name].deep_clone
  77. expected = data[output_name].deep_clone
  78. case expected
  79. when :unsupported then
  80. assert_raises(UnsupportedNodeError) do
  81. processor.process(input)
  82. end
  83. else
  84. extra_expected = []
  85. extra_input = []
  86. _, expected, extra_expected = *expected if
  87. Array === expected and expected.first == :defx
  88. _, input, extra_input = *input if
  89. Array === input and input.first == :defx
  90. # OMG... I can't believe I have to do this this way. these
  91. # hooks are here instead of refactoring this define_method
  92. # body into an assertion. It'll allow subclasses to hook in
  93. # and add behavior before or after the processor does it's
  94. # thing. If you go the body refactor route, some of the
  95. # RawParseTree test casese fail for completely bogus reasons.
  96. before_process_hook klass, node, data, input_name, output_name
  97. refute_nil data[input_name], "testcase does not exist?"
  98. @result = processor.process input
  99. assert_equal(expected, @result,
  100. "failed on input: #{data[input_name].inspect}")
  101. after_process_hook klass, node, data, input_name, output_name
  102. extra_input.each do |extra|
  103. processor.process(extra)
  104. end
  105. extra = processor.extra_methods rescue []
  106. assert_equal extra_expected, extra
  107. end
  108. end
  109. end
  110. def self.generate_tests klass
  111. install_missing_reporter
  112. clone_same
  113. output_name = klass.name.to_s.sub(/^Test/, '')
  114. input_name = self.previous(output_name)
  115. @@testcases.each do |node, data|
  116. next if [:skip, :unsupported].include? data[input_name]
  117. next if data[output_name] == :skip
  118. generate_test klass, node, data, input_name, output_name
  119. end
  120. end
  121. def self.inherited klass
  122. super
  123. generate_tests klass unless klass.name =~ /TestCase/
  124. end
  125. def self.install_missing_reporter
  126. unless defined? $missing then
  127. $missing = Hash.new { |h,k| h[k] = [] }
  128. at_exit {
  129. at_exit {
  130. warn ""
  131. $missing.sort.each do |name, klasses|
  132. warn "add_tests(#{name.inspect},"
  133. klasses.map! { |klass| " #{klass.inspect} => :same" }
  134. warn klasses.join("\n") + ")"
  135. end
  136. warn ""
  137. }
  138. }
  139. end
  140. end
  141. def self.previous(key, extra=0) # FIX: remove R2C code
  142. idx = @@testcase_order.index(key)
  143. raise "Unknown class #{key} in @@testcase_order" if idx.nil?
  144. case key
  145. when "RubyToRubyC" then
  146. idx -= 1
  147. end
  148. @@testcase_order[idx - 1 - extra]
  149. end
  150. def self.testcase_order; @@testcase_order; end
  151. def self.testcases; @@testcases; end
  152. def self.unsupported_tests *tests
  153. tests.flatten.each do |name|
  154. add_test name, :unsupported
  155. end
  156. end
  157. ############################################################
  158. # Shared TestCases:
  159. @@testcase_order = %w(Ruby RawParseTree ParseTree)
  160. @@testcases = Hash.new { |h,k| h[k] = {} }
  161. add_tests("alias",
  162. "Ruby" => "class X\n alias :y :x\nend",
  163. "RawParseTree" => [:class, :X, nil,
  164. [:scope, [:alias, [:lit, :y], [:lit, :x]]]],
  165. "ParseTree" => s(:class, :X, nil,
  166. s(:scope, s(:alias, s(:lit, :y), s(:lit, :x)))))
  167. add_tests("alias_ugh",
  168. "Ruby" => "class X\n alias y x\nend",
  169. "RawParseTree" => [:class, :X, nil,
  170. [:scope, [:alias, [:lit, :y], [:lit, :x]]]],
  171. "ParseTree" => s(:class, :X, nil,
  172. s(:scope, s(:alias, s(:lit, :y), s(:lit, :x)))),
  173. "Ruby2Ruby" => "class X\n alias :y :x\nend")
  174. add_tests("and",
  175. "Ruby" => "(a and b)",
  176. "RawParseTree" => [:and, [:vcall, :a], [:vcall, :b]],
  177. "ParseTree" => s(:and,
  178. s(:call, nil, :a, s(:arglist)),
  179. s(:call, nil, :b, s(:arglist))))
  180. add_tests("argscat_inside",
  181. "Ruby" => "a = [b, *c]",
  182. "RawParseTree" => [:lasgn, :a,
  183. [:argscat,
  184. [:array, [:vcall, :b]], [:vcall, :c]]],
  185. "ParseTree" => s(:lasgn, :a,
  186. s(:array,
  187. s(:call, nil, :b, s(:arglist)),
  188. s(:splat, s(:call, nil, :c, s(:arglist))))))
  189. add_tests("argscat_svalue",
  190. "Ruby" => "a = b, c, *d",
  191. "RawParseTree" => [:lasgn, :a,
  192. [:svalue,
  193. [:argscat,
  194. [:array, [:vcall, :b], [:vcall, :c]],
  195. [:vcall, :d]]]],
  196. "ParseTree" => s(:lasgn, :a,
  197. s(:svalue,
  198. s(:array,
  199. s(:call, nil, :b, s(:arglist)),
  200. s(:call, nil, :c, s(:arglist)),
  201. s(:splat,
  202. s(:call, nil, :d, s(:arglist)))))))
  203. add_tests("argspush",
  204. "Ruby" => "a[*b] = c",
  205. "RawParseTree" => [:attrasgn,
  206. [:vcall, :a],
  207. :[]=,
  208. [:argspush,
  209. [:splat,
  210. [:vcall, :b]],
  211. [:vcall, :c]]],
  212. "ParseTree" => s(:attrasgn,
  213. s(:call, nil, :a, s(:arglist)),
  214. :[]=,
  215. s(:arglist,
  216. s(:splat,
  217. s(:call, nil, :b, s(:arglist))),
  218. s(:call, nil, :c, s(:arglist)))))
  219. add_tests("array",
  220. "Ruby" => "[1, :b, \"c\"]",
  221. "RawParseTree" => [:array, [:lit, 1], [:lit, :b], [:str, "c"]],
  222. "ParseTree" => s(:array, s(:lit, 1), s(:lit, :b), s(:str, "c")))
  223. add_tests("array_pct_W",
  224. "Ruby" => "%W[a b c]",
  225. "RawParseTree" => [:array, [:str, "a"], [:str, "b"], [:str, "c"]],
  226. "ParseTree" => s(:array,
  227. s(:str, "a"), s(:str, "b"), s(:str, "c")),
  228. "Ruby2Ruby" => "[\"a\", \"b\", \"c\"]")
  229. add_tests("array_pct_W_dstr",
  230. "Ruby" => "%W[a #\{@b} c]",
  231. "RawParseTree" => [:array,
  232. [:str, "a"],
  233. [:dstr, "", [:evstr, [:ivar, :@b]]],
  234. [:str, "c"]],
  235. "ParseTree" => s(:array,
  236. s(:str, "a"),
  237. s(:dstr, "", s(:evstr, s(:ivar, :@b))),
  238. s(:str, "c")),
  239. "Ruby2Ruby" => "[\"a\", \"#\{@b}\", \"c\"]")
  240. add_tests("array_pct_w",
  241. "Ruby" => "%w[a b c]",
  242. "RawParseTree" => [:array, [:str, "a"], [:str, "b"], [:str, "c"]],
  243. "ParseTree" => s(:array,
  244. s(:str, "a"), s(:str, "b"), s(:str, "c")),
  245. "Ruby2Ruby" => "[\"a\", \"b\", \"c\"]")
  246. add_tests("array_pct_w_dstr",
  247. "Ruby" => "%w[a #\{@b} c]",
  248. "RawParseTree" => [:array,
  249. [:str, "a"],
  250. [:str, "#\{@b}"],
  251. [:str, "c"]],
  252. "ParseTree" => s(:array,
  253. s(:str, "a"),
  254. s(:str, "#\{@b}"),
  255. s(:str, "c")),
  256. "Ruby2Ruby" => "[\"a\", \"\\\#{@b}\", \"c\"]") # TODO: huh?
  257. add_tests("attrasgn",
  258. "Ruby" => "y = 0\n42.method = y\n",
  259. "RawParseTree" => [:block,
  260. [:lasgn, :y, [:lit, 0]],
  261. [:attrasgn, [:lit, 42], :method=,
  262. [:array, [:lvar, :y]]]],
  263. "ParseTree" => s(:block,
  264. s(:lasgn, :y, s(:lit, 0)),
  265. s(:attrasgn, s(:lit, 42), :method=,
  266. s(:arglist, s(:lvar, :y)))))
  267. add_tests("attrasgn_index_equals",
  268. "Ruby" => "a[42] = 24",
  269. "RawParseTree" => [:attrasgn, [:vcall, :a], :[]=,
  270. [:array, [:lit, 42], [:lit, 24]]],
  271. "ParseTree" => s(:attrasgn,
  272. s(:call, nil, :a, s(:arglist)),
  273. :[]=,
  274. s(:arglist, s(:lit, 42), s(:lit, 24))))
  275. add_tests("attrasgn_index_equals_space",
  276. "Ruby" => "a = []; a [42] = 24",
  277. "RawParseTree" => [:block,
  278. [:lasgn, :a, [:zarray]],
  279. [:attrasgn, [:lvar, :a], :[]=,
  280. [:array, [:lit, 42], [:lit, 24]]]],
  281. "ParseTree" => s(:block,
  282. s(:lasgn, :a, s(:array)),
  283. s(:attrasgn, s(:lvar, :a), :[]=,
  284. s(:arglist, s(:lit, 42), s(:lit, 24)))),
  285. "Ruby2Ruby" => "a = []\na[42] = 24\n")
  286. add_tests("attrset",
  287. "Ruby" => [Examples, :writer=],
  288. "RawParseTree" => [:defn, :writer=, [:attrset, :@writer]],
  289. "ParseTree" => s(:defn, :writer=,
  290. s(:args, :arg),
  291. s(:attrset, :@writer)),
  292. "Ruby2Ruby" => "attr_writer :writer")
  293. add_tests("back_ref",
  294. "Ruby" => "[$&, $`, $', $+]",
  295. "RawParseTree" => [:array,
  296. [:back_ref, :&],
  297. [:back_ref, :"`"],
  298. [:back_ref, :"'"],
  299. [:back_ref, :+]],
  300. "ParseTree" => s(:array,
  301. s(:back_ref, :&),
  302. s(:back_ref, :"`"),
  303. s(:back_ref, :"'"),
  304. s(:back_ref, :+)))
  305. add_tests("begin",
  306. "Ruby" => "begin\n (1 + 1)\nend",
  307. "RawParseTree" => [:call, [:lit, 1], :+, [:array, [:lit, 1]]],
  308. "ParseTree" => s(:call, s(:lit, 1), :+,
  309. s(:arglist, s(:lit, 1))),
  310. "Ruby2Ruby" => "(1 + 1)")
  311. add_tests("begin_def",
  312. "Ruby" => "def m\n begin\n\n end\nend",
  313. "RawParseTree" => [:defn, :m, [:scope, [:block, [:args], [:nil]]]],
  314. "ParseTree" => s(:defn, :m, s(:args),
  315. s(:scope, s(:block, s(:nil)))),
  316. "Ruby2Ruby" => "def m\n # do nothing\nend")
  317. add_tests("begin_rescue_ensure",
  318. "Ruby" => "begin\n a\nrescue\n # do nothing\nensure\n # do nothing\nend",
  319. "RawParseTree" => [:ensure,
  320. [:rescue,
  321. [:vcall, :a],
  322. [:resbody, nil]],
  323. [:nil]],
  324. "ParseTree" => s(:ensure,
  325. s(:rescue,
  326. s(:call, nil, :a, s(:arglist)),
  327. s(:resbody, s(:array), nil)),
  328. s(:nil)))
  329. add_tests("begin_rescue_ensure_all_empty",
  330. "Ruby" => "begin\n # do nothing\nrescue\n # do nothing\nensure\n # do nothing\nend",
  331. "RawParseTree" => [:ensure,
  332. [:rescue,
  333. [:resbody, nil]],
  334. [:nil]],
  335. "ParseTree" => s(:ensure,
  336. s(:rescue,
  337. s(:resbody, s(:array), nil)),
  338. s(:nil)))
  339. add_tests("begin_rescue_twice",
  340. "Ruby" => "begin\n a\nrescue => mes\n # do nothing\nend\nbegin\n b\nrescue => mes\n # do nothing\nend\n",
  341. "RawParseTree" => [:block,
  342. [:rescue,
  343. [:vcall, :a],
  344. [:resbody, nil,
  345. [:lasgn, :mes, [:gvar, :$!]]]],
  346. [:rescue,
  347. [:vcall, :b],
  348. [:resbody, nil,
  349. [:lasgn, :mes, [:gvar, :$!]]]]],
  350. "ParseTree" => s(:block,
  351. s(:rescue,
  352. s(:call, nil, :a, s(:arglist)),
  353. s(:resbody,
  354. s(:array, s(:lasgn, :mes, s(:gvar, :$!))),
  355. nil)),
  356. s(:rescue,
  357. s(:call, nil, :b, s(:arglist)),
  358. s(:resbody,
  359. s(:array,
  360. s(:lasgn, :mes, s(:gvar, :$!))),
  361. nil))))
  362. add_tests("begin_rescue_twice_mri_verbose_flag",
  363. "RawParseTree" => [:block,
  364. [:rescue, # no begin
  365. [:vcall, :a],
  366. [:resbody, nil,
  367. [:lasgn, :mes, [:gvar, :$!]]]],
  368. [:rescue,
  369. [:vcall, :b],
  370. [:resbody, nil,
  371. [:lasgn, :mes, [:gvar, :$!]]]]])
  372. copy_test_case "begin_rescue_twice", "Ruby"
  373. copy_test_case "begin_rescue_twice", "ParseTree"
  374. add_tests("block_attrasgn",
  375. "Ruby" => "def self.setup(ctx)\n bind = allocate\n bind.context = ctx\n return bind\nend",
  376. "RawParseTree" => [:defs, [:self], :setup,
  377. [:scope,
  378. [:block,
  379. [:args, :ctx],
  380. [:lasgn, :bind, [:vcall, :allocate]],
  381. [:attrasgn, [:lvar, :bind], :context=,
  382. [:array, [:lvar, :ctx]]],
  383. [:return, [:lvar, :bind]]]]],
  384. "ParseTree" => s(:defs, s(:self), :setup,
  385. s(:args, :ctx),
  386. s(:scope,
  387. s(:block,
  388. s(:lasgn, :bind,
  389. s(:call, nil, :allocate, s(:arglist))),
  390. s(:attrasgn, s(:lvar, :bind), :context=,
  391. s(:arglist, s(:lvar, :ctx))),
  392. s(:return, s(:lvar, :bind))))))
  393. add_tests("block_lasgn",
  394. "Ruby" => "x = (y = 1\n(y + 2))",
  395. "RawParseTree" => [:lasgn, :x,
  396. [:block,
  397. [:lasgn, :y, [:lit, 1]],
  398. [:call, [:lvar, :y], :+, [:array, [:lit, 2]]]]],
  399. "ParseTree" => s(:lasgn, :x,
  400. s(:block,
  401. s(:lasgn, :y, s(:lit, 1)),
  402. s(:call, s(:lvar, :y), :+,
  403. s(:arglist, s(:lit, 2))))))
  404. add_tests("block_mystery_block",
  405. "Ruby" => "a(b) do\n if b then\n true\n else\n c = false\n d { |x| c = true }\n c\n end\nend",
  406. "RawParseTree" => [:iter,
  407. [:fcall, :a, [:array, [:vcall, :b]]],
  408. nil,
  409. [:if,
  410. [:vcall, :b],
  411. [:true],
  412. [:block,
  413. [:dasgn_curr, :c, [:false]],
  414. [:iter,
  415. [:fcall, :d],
  416. [:dasgn_curr, :x],
  417. [:dasgn, :c, [:true]]],
  418. [:dvar, :c]]]],
  419. "ParseTree" => s(:iter,
  420. s(:call, nil, :a,
  421. s(:arglist, s(:call, nil, :b, s(:arglist)))),
  422. nil,
  423. s(:if,
  424. s(:call, nil, :b, s(:arglist)),
  425. s(:true),
  426. s(:block,
  427. s(:lasgn, :c, s(:false)),
  428. s(:iter,
  429. s(:call, nil, :d, s(:arglist)),
  430. s(:lasgn, :x),
  431. s(:lasgn, :c, s(:true))),
  432. s(:lvar, :c)))))
  433. add_tests("block_pass_args_and_splat",
  434. "Ruby" => "def blah(*args, &block)\n other(42, *args, &block)\nend",
  435. "RawParseTree" => [:defn, :blah,
  436. [:scope,
  437. [:block,
  438. [:args, :"*args"],
  439. [:block_arg, :block],
  440. [:block_pass,
  441. [:lvar, :block],
  442. [:fcall, :other,
  443. [:argscat,
  444. [:array, [:lit, 42]], [:lvar, :args]]]]]]],
  445. "ParseTree" => s(:defn, :blah,
  446. s(:args, :"*args", :"&block"),
  447. s(:scope,
  448. s(:block,
  449. s(:call, nil, :other,
  450. s(:arglist,
  451. s(:lit, 42),
  452. s(:splat, s(:lvar, :args)),
  453. s(:block_pass, s(:lvar, :block))))))))
  454. add_tests("block_pass_call_0",
  455. "Ruby" => "a.b(&c)",
  456. "RawParseTree" => [:block_pass,
  457. [:vcall, :c], [:call, [:vcall, :a], :b]],
  458. "ParseTree" => s(:call,
  459. s(:call, nil, :a, s(:arglist)),
  460. :b,
  461. s(:arglist,
  462. s(:block_pass,
  463. s(:call, nil, :c, s(:arglist))))))
  464. add_tests("block_pass_call_1",
  465. "Ruby" => "a.b(4, &c)",
  466. "RawParseTree" => [:block_pass,
  467. [:vcall, :c],
  468. [:call, [:vcall, :a], :b, [:array, [:lit, 4]]]],
  469. "ParseTree" => s(:call,
  470. s(:call, nil, :a, s(:arglist)),
  471. :b,
  472. s(:arglist,
  473. s(:lit, 4),
  474. s(:block_pass,
  475. s(:call, nil, :c, s(:arglist))))))
  476. add_tests("block_pass_call_n",
  477. "Ruby" => "a.b(1, 2, 3, &c)",
  478. "RawParseTree" => [:block_pass,
  479. [:vcall, :c],
  480. [:call, [:vcall, :a], :b,
  481. [:array, [:lit, 1], [:lit, 2], [:lit, 3]]]],
  482. "ParseTree" => s(:call,
  483. s(:call, nil, :a, s(:arglist)),
  484. :b,
  485. s(:arglist,
  486. s(:lit, 1), s(:lit, 2), s(:lit, 3),
  487. s(:block_pass,
  488. s(:call, nil, :c, s(:arglist))))))
  489. add_tests("block_pass_fcall_0",
  490. "Ruby" => "a(&b)",
  491. "RawParseTree" => [:block_pass, [:vcall, :b], [:fcall, :a]],
  492. "ParseTree" => s(:call, nil, :a,
  493. s(:arglist,
  494. s(:block_pass,
  495. s(:call, nil, :b, s(:arglist))))))
  496. add_tests("block_pass_fcall_1",
  497. "Ruby" => "a(4, &b)",
  498. "RawParseTree" => [:block_pass,
  499. [:vcall, :b],
  500. [:fcall, :a, [:array, [:lit, 4]]]],
  501. "ParseTree" => s(:call, nil, :a,
  502. s(:arglist,
  503. s(:lit, 4),
  504. s(:block_pass,
  505. s(:call, nil, :b, s(:arglist))))))
  506. add_tests("block_pass_fcall_n",
  507. "Ruby" => "a(1, 2, 3, &b)",
  508. "RawParseTree" => [:block_pass,
  509. [:vcall, :b],
  510. [:fcall, :a,
  511. [:array, [:lit, 1], [:lit, 2], [:lit, 3]]]],
  512. "ParseTree" => s(:call, nil, :a,
  513. s(:arglist,
  514. s(:lit, 1), s(:lit, 2), s(:lit, 3),
  515. s(:block_pass,
  516. s(:call, nil, :b, s(:arglist))))))
  517. add_tests("block_pass_omgwtf",
  518. "Ruby" => "define_attr_method(:x, :sequence_name, &Proc.new { |*args| nil })",
  519. "RawParseTree" => [:block_pass,
  520. [:iter,
  521. [:call, [:const, :Proc], :new],
  522. [:masgn, nil, [:dasgn_curr, :args], nil],
  523. [:nil]],
  524. [:fcall, :define_attr_method,
  525. [:array, [:lit, :x], [:lit, :sequence_name]]]],
  526. "ParseTree" => s(:call, nil, :define_attr_method,
  527. s(:arglist,
  528. s(:lit, :x),
  529. s(:lit, :sequence_name),
  530. s(:block_pass,
  531. s(:iter,
  532. s(:call, s(:const, :Proc), :new,
  533. s(:arglist)),
  534. s(:masgn,
  535. s(:array, s(:splat, s(:lasgn, :args)))),
  536. s(:nil))))))
  537. add_tests("block_pass_splat",
  538. "Ruby" => "def blah(*args, &block)\n other(*args, &block)\nend",
  539. "RawParseTree" => [:defn, :blah,
  540. [:scope,
  541. [:block,
  542. [:args, :"*args"],
  543. [:block_arg, :block],
  544. [:block_pass,
  545. [:lvar, :block],
  546. [:fcall, :other,
  547. [:splat, [:lvar, :args]]]]]]],
  548. "ParseTree" => s(:defn, :blah,
  549. s(:args, :"*args", :"&block"),
  550. s(:scope,
  551. s(:block,
  552. s(:call, nil, :other,
  553. s(:arglist,
  554. s(:splat, s(:lvar, :args)),
  555. s(:block_pass, s(:lvar, :block))))))))
  556. add_tests("block_pass_thingy",
  557. "Ruby" => "r.read_body(dest, &block)",
  558. "RawParseTree" => [:block_pass,
  559. [:vcall, :block],
  560. [:call, [:vcall, :r], :read_body,
  561. [:array, [:vcall, :dest]]]],
  562. "ParseTree" => s(:call,
  563. s(:call, nil, :r, s(:arglist)),
  564. :read_body,
  565. s(:arglist,
  566. s(:call, nil, :dest, s(:arglist)),
  567. s(:block_pass,
  568. s(:call, nil, :block, s(:arglist))))))
  569. add_tests("block_stmt_after",
  570. "Ruby" => "def f\n begin\n b\n rescue\n c\n end\n\n d\nend",
  571. "RawParseTree" => [:defn, :f,
  572. [:scope,
  573. [:block,
  574. [:args],
  575. [:rescue,
  576. [:vcall, :b],
  577. [:resbody, nil, [:vcall, :c]]],
  578. [:vcall, :d]]]],
  579. "ParseTree" => s(:defn, :f,
  580. s(:args),
  581. s(:scope,
  582. s(:block,
  583. s(:rescue,
  584. s(:call, nil, :b, s(:arglist)),
  585. s(:resbody,
  586. s(:array),
  587. s(:call, nil, :c, s(:arglist)))),
  588. s(:call, nil, :d, s(:arglist))))),
  589. "Ruby2Ruby" => "def f\n b rescue c\n d\nend")
  590. add_tests("block_stmt_after_mri_verbose_flag",
  591. "RawParseTree" => [:defn, :f,
  592. [:scope,
  593. [:block,
  594. [:args],
  595. [:rescue, # no begin
  596. [:vcall, :b],
  597. [:resbody, nil, [:vcall, :c]]],
  598. [:vcall, :d]]]])
  599. copy_test_case "block_stmt_after", "Ruby"
  600. copy_test_case "block_stmt_after", "ParseTree"
  601. copy_test_case "block_stmt_after", "Ruby2Ruby"
  602. add_tests("block_stmt_before",
  603. "Ruby" => "def f\n a\n begin\n b\n rescue\n c\n end\nend",
  604. "RawParseTree" => [:defn, :f,
  605. [:scope,
  606. [:block,
  607. [:args],
  608. [:vcall, :a],
  609. [:rescue, [:vcall, :b],
  610. [:resbody, nil, [:vcall, :c]]]]]],
  611. "ParseTree" => s(:defn, :f,
  612. s(:args),
  613. s(:scope,
  614. s(:block,
  615. s(:call, nil, :a, s(:arglist)),
  616. s(:rescue, s(:call, nil, :b, s(:arglist)),
  617. s(:resbody,
  618. s(:array),
  619. s(:call, nil, :c, s(:arglist))))))),
  620. "Ruby2Ruby" => "def f\n a\n b rescue c\nend")
  621. # oddly... this one doesn't HAVE any differences when verbose... new?
  622. copy_test_case "block_stmt_before", "Ruby"
  623. copy_test_case "block_stmt_before", "ParseTree"
  624. copy_test_case "block_stmt_before", "RawParseTree"
  625. copy_test_case "block_stmt_before", "Ruby2Ruby"
  626. add_tests("block_stmt_both",
  627. "Ruby" => "def f\n a\n begin\n b\n rescue\n c\n end\n d\nend",
  628. "RawParseTree" => [:defn, :f,
  629. [:scope,
  630. [:block,
  631. [:args],
  632. [:vcall, :a],
  633. [:rescue,
  634. [:vcall, :b],
  635. [:resbody,
  636. nil,
  637. [:vcall, :c]]],
  638. [:vcall, :d]]]],
  639. "ParseTree" => s(:defn, :f, s(:args),
  640. s(:scope,
  641. s(:block,
  642. s(:call, nil, :a, s(:arglist)),
  643. s(:rescue,
  644. s(:call, nil, :b, s(:arglist)),
  645. s(:resbody,
  646. s(:array),
  647. s(:call, nil, :c, s(:arglist)))),
  648. s(:call, nil, :d, s(:arglist))))),
  649. "Ruby2Ruby" => "def f\n a\n b rescue c\n d\nend")
  650. add_tests("block_stmt_both_mri_verbose_flag",
  651. "RawParseTree" => [:defn, :f,
  652. [:scope,
  653. [:block,
  654. [:args],
  655. [:vcall, :a],
  656. [:rescue, # no begin
  657. [:vcall, :b],
  658. [:resbody,
  659. nil,
  660. [:vcall, :c]]],
  661. [:vcall, :d]]]])
  662. copy_test_case "block_stmt_both", "Ruby"
  663. copy_test_case "block_stmt_both", "ParseTree"
  664. copy_test_case "block_stmt_both", "Ruby2Ruby"
  665. add_tests("bmethod",
  666. "Ruby" => [Examples, :unsplatted],
  667. "RawParseTree" => [:defn, :unsplatted,
  668. [:bmethod,
  669. [:dasgn_curr, :x],
  670. [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]],
  671. "ParseTree" => s(:defn, :unsplatted,
  672. s(:args, :x),
  673. s(:scope,
  674. s(:block,
  675. s(:call,
  676. s(:lvar, :x),
  677. :+,
  678. s(:arglist, s(:lit, 1)))))),
  679. "Ruby2Ruby" => "def unsplatted(x)\n (x + 1)\nend")
  680. add_tests("bmethod_noargs",
  681. "Ruby" => [Examples, :bmethod_noargs],
  682. "RawParseTree" => [:defn, :bmethod_noargs,
  683. [:bmethod,
  684. nil,
  685. [:call,
  686. [:vcall, :x], :"+", [:array, [:lit, 1]]]]],
  687. "ParseTree" => s(:defn, :bmethod_noargs,
  688. s(:args),
  689. s(:scope,
  690. s(:block,
  691. s(:call,
  692. s(:call, nil, :x, s(:arglist)),
  693. :"+",
  694. s(:arglist, s(:lit, 1)))))),
  695. "Ruby2Ruby" => "def bmethod_noargs\n (x + 1)\nend")
  696. add_tests("bmethod_splat",
  697. "Ruby" => [Examples, :splatted],
  698. "RawParseTree" => [:defn, :splatted,
  699. [:bmethod,
  700. [:masgn, nil, [:dasgn_curr, :args], nil],
  701. [:block,
  702. [:dasgn_curr, :y,
  703. [:call, [:dvar, :args], :first]],
  704. [:call, [:dvar, :y], :+,
  705. [:array, [:lit, 42]]]]]],
  706. "ParseTree" => s(:defn, :splatted,
  707. s(:args, :"*args"),
  708. s(:scope,
  709. s(:block,
  710. s(:lasgn, :y,
  711. s(:call, s(:lvar, :args), :first,
  712. s(:arglist))),
  713. s(:call, s(:lvar, :y), :+,
  714. s(:arglist, s(:lit, 42)))))),
  715. "Ruby2Ruby" => "def splatted(*args)\n y = args.first\n (y + 42)\nend")
  716. add_tests("break",
  717. "Ruby" => "loop { break if true }",
  718. "RawParseTree" => [:iter,
  719. [:fcall, :loop], nil,
  720. [:if, [:true], [:break], nil]],
  721. "ParseTree" => s(:iter,
  722. s(:call, nil, :loop, s(:arglist)), nil,
  723. s(:if, s(:true), s(:break), nil)))
  724. add_tests("break_arg",
  725. "Ruby" => "loop { break 42 if true }",
  726. "RawParseTree" => [:iter,
  727. [:fcall, :loop], nil,
  728. [:if, [:true], [:break, [:lit, 42]], nil]],
  729. "ParseTree" => s(:iter,
  730. s(:call, nil, :loop, s(:arglist)), nil,
  731. s(:if, s(:true), s(:break, s(:lit, 42)), nil)))
  732. add_tests("call",
  733. "Ruby" => "self.method",
  734. "RawParseTree" => [:call, [:self], :method],
  735. "ParseTree" => s(:call, s(:self), :method, s(:arglist)))
  736. add_tests("call_arglist",
  737. "Ruby" => "o.puts(42)",
  738. "RawParseTree" => [:call, [:vcall, :o], :puts,
  739. [:array, [:lit, 42]]],
  740. "ParseTree" => s(:call, s(:call, nil, :o, s(:arglist)), :puts,
  741. s(:arglist, s(:lit, 42))))
  742. add_tests("call_arglist_hash",
  743. "Ruby" => "o.m(:a => 1, :b => 2)",
  744. "RawParseTree" => [:call,
  745. [:vcall, :o], :m,
  746. [:array,
  747. [:hash,
  748. [:lit, :a], [:lit, 1],
  749. [:lit, :b], [:lit, 2]]]],
  750. "ParseTree" => s(:call,
  751. s(:call, nil, :o, s(:arglist)), :m,
  752. s(:arglist,
  753. s(:hash,
  754. s(:lit, :a), s(:lit, 1),
  755. s(:lit, :b), s(:lit, 2)))))
  756. add_tests("call_arglist_norm_hash",
  757. "Ruby" => "o.m(42, :a => 1, :b => 2)",
  758. "RawParseTree" => [:call,
  759. [:vcall, :o], :m,
  760. [:array,
  761. [:lit, 42],
  762. [:hash,
  763. [:lit, :a], [:lit, 1],
  764. [:lit, :b], [:lit, 2]]]],
  765. "ParseTree" => s(:call,
  766. s(:call, nil, :o, s(:arglist)), :m,
  767. s(:arglist,
  768. s(:lit, 42),
  769. s(:hash,
  770. s(:lit, :a), s(:lit, 1),
  771. s(:lit, :b), s(:lit, 2)))))
  772. add_tests("call_arglist_norm_hash_splat",
  773. "Ruby" => "o.m(42, :a => 1, :b => 2, *c)",
  774. "RawParseTree" => [:call,
  775. [:vcall, :o], :m,
  776. [:argscat,
  777. [:array,
  778. [:lit, 42],
  779. [:hash,
  780. [:lit, :a], [:lit, 1],
  781. [:lit, :b], [:lit, 2]]],
  782. [:vcall, :c]]],
  783. "ParseTree" => s(:call,
  784. s(:call, nil, :o, s(:arglist)), :m,
  785. s(:arglist,
  786. s(:lit, 42),
  787. s(:hash,
  788. s(:lit, :a), s(:lit, 1),
  789. s(:lit, :b), s(:lit, 2)),
  790. s(:splat, s(:call, nil, :c, s(:arglist))))))
  791. add_tests("call_arglist_space",
  792. "Ruby" => "a (1,2,3)",
  793. "RawParseTree" => [:fcall, :a,
  794. [:array, [:lit, 1], [:lit, 2], [:lit, 3]]],
  795. "ParseTree" => s(:call, nil, :a,
  796. s(:arglist,
  797. s(:lit, 1), s(:lit, 2), s(:lit, 3))),
  798. "Ruby2Ruby" => "a(1, 2, 3)")
  799. add_tests("call_command",
  800. "Ruby" => "1.b(c)",
  801. "RawParseTree" => [:call, [:lit, 1], :b, [:array, [:vcall, :c]]],
  802. "ParseTree" => s(:call,
  803. s(:lit, 1),
  804. :b,
  805. s(:arglist, s(:call, nil, :c, s(:arglist)))))
  806. add_tests("call_expr",
  807. "Ruby" => "(v = (1 + 1)).zero?",
  808. "RawParseTree" => [:call,
  809. [:lasgn, :v,
  810. [:call, [:lit, 1], :+, [:array, [:lit, 1]]]],
  811. :zero?],
  812. "ParseTree" => s(:call,
  813. s(:lasgn, :v,
  814. s(:call, s(:lit, 1), :+,
  815. s(:arglist, s(:lit, 1)))),
  816. :zero?, s(:arglist)))
  817. add_tests("call_index",
  818. "Ruby" => "a = []\na[42]\n",
  819. "RawParseTree" => [:block,
  820. [:lasgn, :a, [:zarray]],
  821. [:call, [:lvar, :a], :[], [:array, [:lit, 42]]]],
  822. "ParseTree" => s(:block,
  823. s(:lasgn, :a, s(:array)),
  824. s(:call, s(:lvar, :a), :[],
  825. s(:arglist, s(:lit, 42)))))
  826. add_tests("call_index_no_args",
  827. "Ruby" => "a[]",
  828. "RawParseTree" => [:call, [:vcall, :a], :[]],
  829. "ParseTree" => s(:call, s(:call, nil, :a, s(:arglist)),
  830. :[], s(:arglist)))
  831. add_tests("call_index_space",
  832. "Ruby" => "a = []\na [42]\n",
  833. "RawParseTree" => [:block,
  834. [:lasgn, :a, [:zarray]],
  835. [:call, [:lvar, :a], :[], [:array, [:lit, 42]]]],
  836. "ParseTree" => s(:block,
  837. s(:lasgn, :a, s(:array)),
  838. s(:call, s(:lvar, :a), :[],
  839. s(:arglist, s(:lit, 42)))),
  840. "Ruby2Ruby" => "a = []\na[42]\n")
  841. add_tests("call_unary_neg",
  842. "Ruby" => "-2**31",
  843. "RawParseTree" => [:call,
  844. [:call, [:lit, 2], :**, [:array, [:lit, 31]]],
  845. :-@],
  846. "ParseTree" => s(:call,
  847. s(:call,
  848. s(:lit, 2),
  849. :**,
  850. s(:arglist, s(:lit, 31))),
  851. :-@, s(:arglist)),
  852. "Ruby2Ruby" => "-(2 ** 31)")
  853. add_tests("case",
  854. "Ruby" => "var = 2\nresult = \"\"\ncase var\nwhen 1 then\n puts(\"something\")\n result = \"red\"\nwhen 2, 3 then\n result = \"yellow\"\nwhen 4 then\n # do nothing\nelse\n result = \"green\"\nend\ncase result\nwhen \"red\" then\n var = 1\nwhen \"yellow\" then\n var = 2\nwhen \"green\" then\n var = 3\nelse\n # do nothing\nend\n",
  855. "RawParseTree" => [:block,
  856. [:lasgn, :var, [:lit, 2]],
  857. [:lasgn, :result, [:str, ""]],
  858. [:case,
  859. [:lvar, :var],
  860. [:when,
  861. [:array, [:lit, 1]],
  862. [:block,
  863. [:fcall, :puts,
  864. [:array, [:str, "something"]]],
  865. [:lasgn, :result, [:str, "red"]]]],
  866. [:when,
  867. [:array, [:lit, 2], [:lit, 3]],
  868. [:lasgn, :result, [:str, "yellow"]]],
  869. [:when, [:array, [:lit, 4]], nil],
  870. [:lasgn, :result, [:str, "green"]]],
  871. [:case,
  872. [:lvar, :result],
  873. [:when, [:array, [:str, "red"]],
  874. [:lasgn, :var, [:lit, 1]]],
  875. [:when, [:array, [:str, "yellow"]],
  876. [:lasgn, :var, [:lit, 2]]],
  877. [:when, [:array, [:str, "green"]],
  878. [:lasgn, :var, [:lit, 3]]],
  879. nil]],
  880. "ParseTree" => s(:block,
  881. s(:lasgn, :var, s(:lit, 2)),
  882. s(:lasgn, :result, s(:str, "")),
  883. s(:case,
  884. s(:lvar, :var),
  885. s(:when,
  886. s(:array, s(:lit, 1)),
  887. s(:block,
  888. s(:call, nil, :puts,
  889. s(:arglist, s(:str, "something"))),
  890. s(:lasgn, :result, s(:str, "red")))),
  891. s(:when,
  892. s(:array, s(:lit, 2), s(:lit, 3)),
  893. s(:lasgn, :result, s(:str, "yellow"))),
  894. s(:when, s(:array, s(:lit, 4)), nil),
  895. s(:lasgn, :result, s(:str, "green"))),
  896. s(:case,
  897. s(:lvar, :result),
  898. s(:when, s(:array, s(:str, "red")),
  899. s(:lasgn, :var, s(:lit, 1))),
  900. s(:when, s(:array, s(:str, "yellow")),
  901. s(:lasgn, :var, s(:lit, 2))),
  902. s(:when, s(:array, s(:str, "green")),
  903. s(:lasgn, :var, s(:lit, 3))),
  904. nil)))
  905. add_tests("case_nested",
  906. "Ruby" => "var1 = 1\nvar2 = 2\nresult = nil\ncase var1\nwhen 1 then\n case var2\n when 1 then\n result = 1\n when 2 then\n result = 2\n else\n result = 3\n end\nwhen 2 then\n case var2\n when 1 then\n result = 4\n when 2 then\n result = 5\n else\n result = 6\n end\nelse\n result = 7\nend\n",
  907. "RawParseTree" => [:block,
  908. [:lasgn, :var1, [:lit, 1]],
  909. [:lasgn, :var2, [:lit, 2]],
  910. [:lasgn, :result, [:nil]],
  911. [:case,
  912. [:lvar, :var1],
  913. [:when, [:array, [:lit, 1]],
  914. [:case,
  915. [:lvar, :var2],
  916. [:when, [:array, [:lit, 1]],
  917. [:lasgn, :result, [:lit, 1]]],
  918. [:when, [:array, [:lit, 2]],
  919. [:lasgn, :result, [:lit, 2]]],
  920. [:lasgn, :result, [:lit, 3]]]],
  921. [:when, [:array, [:lit, 2]],
  922. [:case,
  923. [:lvar, :var2],
  924. [:when, [:array, [:lit, 1]],
  925. [:lasgn, :result, [:lit, 4]]],
  926. [:when, [:array, [:lit, 2]],
  927. [:lasgn, :result, [:lit, 5]]],
  928. [:lasgn, :result, [:lit, 6]]]],
  929. [:lasgn, :result, [:lit, 7]]]],
  930. "ParseTree" => s(:block,
  931. s(:lasgn, :var1, s(:lit, 1)),
  932. s(:lasgn, :var2, s(:lit, 2)),
  933. s(:lasgn, :result, s(:nil)),
  934. s(:case,
  935. s(:lvar, :var1),
  936. s(:when, s(:array, s(:lit, 1)),
  937. s(:case,
  938. s(:lvar, :var2),
  939. s(:when, s(:array, s(:lit, 1)),
  940. s(:lasgn, :result, s(:lit, 1))),
  941. s(:when, s(:array, s(:lit, 2)),
  942. s(:lasgn, :result, s(:lit, 2))),
  943. s(:lasgn, :result, s(:lit, 3)))),
  944. s(:when, s(:array, s(:lit, 2)),
  945. s(:case,
  946. s(:lvar, :var2),
  947. s(:when, s(:array, s(:lit, 1)),
  948. s(:lasgn, :result, s(:lit, 4))),
  949. s(:when, s(:array, s(:lit, 2)),
  950. s(:lasgn, :result, s(:lit, 5))),
  951. s(:lasgn, :result, s(:lit, 6)))),
  952. s(:lasgn, :result, s(:lit, 7)))))
  953. add_tests("case_nested_inner_no_expr",
  954. "Ruby" => "case a\nwhen b then\n case\n when (d and e) then\n f\n else\n # do nothing\n end\nelse\n # do nothing\nend",
  955. "RawParseTree" => [:case, [:vcall, :a],
  956. [:when, [:array, [:vcall, :b]],
  957. [:case, nil,
  958. [:when,
  959. [:array, [:and, [:vcall, :d], [:vcall, :e]]],
  960. [:vcall, :f]],
  961. nil]],
  962. nil],
  963. "ParseTree" => s(:case, s(:call, nil, :a, s(:arglist)),
  964. s(:when,
  965. s(:array, s(:call, nil, :b, s(:arglist))),
  966. s(:case, nil,
  967. s(:when,
  968. s(:array,
  969. s(:and,
  970. s(:call, nil, :d, s(:arglist)),
  971. s(:call, nil, :e, s(:arglist)))),
  972. s(:call, nil, :f, s(:arglist))),
  973. nil)),
  974. nil))
  975. add_tests("case_no_expr",
  976. "Ruby" => "case\nwhen (a == 1) then\n :a\nwhen (a == 2) then\n :b\nelse\n :c\nend",
  977. "RawParseTree" => [:case, nil,
  978. [:when,
  979. [:array,
  980. [:call, [:vcall, :a], :==,
  981. [:array, [:lit, 1]]]],
  982. [:lit, :a]],
  983. [:when,
  984. [:array,
  985. [:call, [:vcall, :a], :==,
  986. [:array, [:lit, 2]]]],
  987. [:lit, :b]],
  988. [:lit, :c]],
  989. "ParseTree" => s(:case, nil,
  990. s(:when,
  991. s(:array,
  992. s(:call,
  993. s(:call, nil, :a, s(:arglist)),
  994. :==,
  995. s(:arglist, s(:lit, 1)))),
  996. s(:lit, :a)),

Large files files are truncated, but you can click here to view the full file