diff -Nru ruby-ruby2ruby-2.3.0/checksums.yaml.gz.sig ruby-ruby2ruby-2.4.1/checksums.yaml.gz.sig --- ruby-ruby2ruby-2.3.0/checksums.yaml.gz.sig 2016-03-30 23:22:41.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/checksums.yaml.gz.sig 2018-07-10 14:01:22.000000000 +0000 @@ -1,3 +1,2 @@ -y.ٻRC fMLͱ-c.26Ue*E7QRCt>3{IQ[M:n) ʈ$,A(.r@V:ݧߨ28ͪz3"h'n,~}2;|5 1yȜ5 ') Z4i5 d X¢<}c5c`Q&¨{2 -M$"½?;S{+gj,bɕ0%ݓp> -~-Kwg \ No newline at end of file +?^E ZLM2r殠+ Lo3*3"Zu;'ѝw +P774#fSY}f{p܅hh+.9/s `M׭t]^;8=^p* @ЦSoI 0%9A;숚4Gd(> lu*$O1 Wed, 01 Aug 2018 02:09:34 +0200 + ruby-ruby2ruby (2.3.0-1) unstable; urgency=medium * Team upload diff -Nru ruby-ruby2ruby-2.3.0/debian/compat ruby-ruby2ruby-2.4.1/debian/compat --- ruby-ruby2ruby-2.3.0/debian/compat 2016-07-22 13:55:00.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/debian/compat 2018-08-01 00:09:34.000000000 +0000 @@ -1 +1 @@ -9 +11 diff -Nru ruby-ruby2ruby-2.3.0/debian/control ruby-ruby2ruby-2.4.1/debian/control --- ruby-ruby2ruby-2.3.0/debian/control 2016-07-22 13:55:00.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/debian/control 2018-08-01 00:09:34.000000000 +0000 @@ -4,14 +4,14 @@ Maintainer: Debian Ruby Extras Maintainers Uploaders: Tobias Grimm , Gunnar Wolf -Build-Depends: debhelper (>= 9~), +Build-Depends: debhelper (>= 11~), gem2deb, ruby-minitest, - ruby-parser (>= 3.1~), - ruby-sexp-processor (>= 4.7~) -Standards-Version: 3.9.8 -Vcs-Git: https://anonscm.debian.org/git/pkg-ruby-extras/ruby-ruby2ruby.git -Vcs-Browser: https://anonscm.debian.org/cgit/pkg-ruby-extras/ruby-ruby2ruby.git + ruby-parser (>= 3.11~), + ruby-sexp-processor (>= 4.11~) +Standards-Version: 4.1.5 +Vcs-Git: https://salsa.debian.org/ruby-team/ruby-ruby2ruby.git +Vcs-Browser: https://salsa.debian.org/ruby-team/ruby-ruby2ruby Homepage: https://github.com/seattlerb/ruby2ruby XS-Ruby-Versions: all Testsuite: autopkgtest-pkg-ruby @@ -20,8 +20,8 @@ Architecture: all XB-Ruby-Versions: ${ruby:Versions} Depends: ruby | ruby-interpreter, - ruby-parser (>= 3.1~), - ruby-sexp-processor (>= 4.7~), + ruby-parser (>= 3.11~), + ruby-sexp-processor (>= 4.11~), ${misc:Depends}, ${shlibs:Depends} Description: Generate pure ruby code easily from ParseTree's Sexps diff -Nru ruby-ruby2ruby-2.3.0/debian/patches/read_ruby2ruby.patch ruby-ruby2ruby-2.4.1/debian/patches/read_ruby2ruby.patch --- ruby-ruby2ruby-2.3.0/debian/patches/read_ruby2ruby.patch 2016-07-22 13:55:00.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/debian/patches/read_ruby2ruby.patch 2018-08-01 00:09:34.000000000 +0000 @@ -2,11 +2,11 @@ For autopkgtest purposes Author: Cédric Boutillier Forwarded: not-needed -Last-Update: 2016-07-22 +Last-Update: 2018-08-01 --- a/test/test_ruby2ruby.rb +++ b/test/test_ruby2ruby.rb -@@ -663,7 +663,11 @@ +@@ -801,7 +801,11 @@ # t new 2 3 tr2r = File.read(__FILE__).split(/\n/)[start+1..__LINE__-2].join("\n") diff -Nru ruby-ruby2ruby-2.3.0/debian/ruby-ruby2ruby.docs ruby-ruby2ruby-2.4.1/debian/ruby-ruby2ruby.docs --- ruby-ruby2ruby-2.3.0/debian/ruby-ruby2ruby.docs 2016-07-22 13:55:00.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/debian/ruby-ruby2ruby.docs 2018-08-01 00:09:34.000000000 +0000 @@ -1 +1 @@ -README.txt +README.rdoc diff -Nru ruby-ruby2ruby-2.3.0/debian/watch ruby-ruby2ruby-2.4.1/debian/watch --- ruby-ruby2ruby-2.3.0/debian/watch 2016-07-22 13:55:00.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/debian/watch 2018-08-01 00:09:34.000000000 +0000 @@ -1,2 +1,2 @@ version=3 -http://pkg-ruby-extras.alioth.debian.org/cgi-bin/gemwatch/ruby2ruby .*/ruby2ruby-(.*).tar.gz +https://gemwatch.debian.net/ruby2ruby .*/ruby2ruby-(.*).tar.gz diff -Nru ruby-ruby2ruby-2.3.0/History.rdoc ruby-ruby2ruby-2.4.1/History.rdoc --- ruby-ruby2ruby-2.3.0/History.rdoc 1970-01-01 00:00:00.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/History.rdoc 2018-07-10 14:01:22.000000000 +0000 @@ -0,0 +1,413 @@ +=== 2.4.1 / 2018-02-15 + +* 2 minor enhancements: + + * Added bitwise ops to BINARY. (david942j) + * Added rewrite_call|if|until|while to normalize `not` in conditions. + +=== 2.4.0 / 2017-07-17 + +* 1 major enhancement: + + * Major overhaul. Process methods no longer mutate arguments. + +* 1 minor enhancement: + + * Now SEXP_STRICT=1 clean. + +* 2 bug fixes: + + * Fixed 2.4 Fixnum deprecation warning + * Fixed for new 24 parser. + +=== 2.3.2 / 2016-11-30 + +* 5 bug fixes: + + * FINALLY fixed a problem with escaping in dstrs. (nex3) + * Fix using match3 on LHS of call. (eqv) + * Fixed handling defn that starts w/ begin+rescue+other stuff. (eqv) + * Fixed return expressions with complex RHS. (eqv) + * Tweaked sexp_processor dependency to ~> 4.6 to sync them better + +=== 2.3.1 / 2016-10-09 + +* 1 minor enhancement: + + * Support more op_asgn nodes. (presidentbeef) + +* 1 bug fix: + + * Fix for non-binary 'binary' calls (eg arity > 1). (presidentbeef) + +=== 2.3.0 / 2016-02-18 + +* 3 minor enhancements: + + * Added support for safe navigation/lonely operator. (presidentbeef) + * Expanded tests for 2.3 support + * Support safe attrasgn. (presidentbeef). + +=== 2.2.0 / 2015-05-27 + +* 1 minor enhancement: + + * Normalized block arg goalposts (always there unless arg slot == 0). + +=== 2.1.4 / 2015-04-13 + +* 1 minor enhancement: + + * Wrap fewer hash values in parentheses. (jaredbeck) + +* 1 bug fix: + + * Fixed handling of kwsplat args. + +=== 2.1.3 / 2014-09-26 + +* 1 bug fix: + + * Fixed handling of kwargs. (joenas) + +=== 2.1.2 / 2014-08-28 + +* 1 bug fix: + + * Fixed readme to point out that deep_clone may be needed. (heathd) + +=== 2.1.1 / 2014-06-09 + +* 1 bug fix: + + * Moved Regexp::CODES out of guard on ::ENC_NONE. (presidentbeef) + +=== 2.1.0 / 2014-04-23 + +* 4 minor enhancements: + + * Don't indent defn body extra if it has a top-level rescue. + * Don't indent defn body until fully processed. + * Don't use simple rescue form if resbody is a return (statement keyword). (eyberg) + * Remove superfluous begin/end for top-level defn rescue. + +=== 2.0.8 / 2014-03-24 + +* 1 bug fix: + + * 2.0/2.1: Fixed support for **kwsplat. (troessner) + +=== 2.0.7 / 2013-12-13 + +* 4 minor enhancements: + + * Add != to list of binary operators. (camertron) *le sigh* + * Clean out cruft from process_masgn that I can't reproduce anymore. + * Extend process_args to deal with masgn (eg: a.b { |(c, d)| ... }). + * Extend process_masgn to deal with both sexps and var lists. + +* 1 bug fix: + + * Ensure proper parens on rescue subexpressions. (Bocete) + +=== 2.0.6 / 2013-06-20 + +* 2 bug fixes: + + * Fixed bug with complex rescue but short enough to trigger 1-liner. (Confusion) + * Fixed multiple expressions inside sclass + +=== 2.0.5 / 2013-04-25 + +* 2 bug fixes: + + * Fixed attrasgn w/ multiple keys: a[x, y] = z. (derula) + * Fixed error w/ attr_* detection when more than 1 ivar/iasgn exist in body. + +=== 2.0.4 / 2013-03-28 + +* 1 bug fix: + + * Fixed attr_* generators in cases where the body isn't idiomatic. (robertfeldt) + +=== 2.0.3 / 2013-02-07 + +* 2 minor enhancements: + + * 1.9: Added support for ! call to go back to (not ...). + * 2nd and 3rd order testing now uses RubyPraser.for_current_ruby for maximal carnage. + +* 1 bug fix: + + * On failure (eg ruby 2.0), fall back to compound RubyParser instance for 2nd & 3rd order testing + +=== 2.0.2 / 2013-01-16 + +* 1 minor enhancement: + + * Updated to ruby_parser 3.1 and up + +=== 2.0.1 / 2012-11-02 + +* 1 bug fix: + + * Fixed dependency on alpha ruby_parser. *sigh* + +=== 2.0.0 / 2012-11-02 + +* 1 minor enhancement: + + * Only do phase 1 testing if $SIMPLE=1. + +* 1 bug fix: + + * Fixed block args processing for RP 3.0 sexp changes + +=== 2.0.0.b1 / 2012-07-27 + +* 4 major enhancements: + + * Made it work without arglist in call. + * Made it work without scope/block in class/module/defn/defs. + * Removed block from resbody + * Removed block from when node + +* 4 minor enhancements: + + * Added debug task to help isolate an error + * Empty hash is now a proper {} + * Refactored and added finish method. + * Switched to new Ruby18Parser to avoid deprecation warnings + +* 4 bug fixes: + + * Fixed call with empty hash arg. (neilconway) + * OMG WTF... removed long decrepit ParseTree dependency + * Removed isolate/rake require to reduce minimum bootstrap to hoe + rake + rake install_plugins (*2) + * Skip 1.9 tests for now. + +=== 1.3.1 / 2011-09-22 + +* 1 minor enhancement: + + * Added parenthesize to add parens in certain contexts. + +* 10 bug fixes: + + * Add newline to 'do nothing' comment in a block... seems contrived. (andreacampi) + * Binary operations not work properly with some complex statements. (smorss) + * Fixed if statements with no body (smorss) + * Fixed logic for call with hash args in various locations (smorss) + * Fixed match3 on an assignment. (smorss) + * Fixed multiple nested rescue/ensure exprs (larsch) + * Fixed process_alias to parenthesize (smorss) + * Fixed process_and to parenthenize only when it makes sense. + * Fixed rescue with 2+ statements in resbody (smorss) + * Regexps with options other than /o were not showing flags. (smorss) + +=== 1.3.0 / 2011-09-01 + +* 1 minor enhancement: + + * output comments for class and method definitions. (pythonic) + +=== 1.2.5 / 2010-09-01 + +* 4 minor enhancements: + + * Added braces to hash args surrounded if in a binary method call. + * Added rewrite_resbody to double check structure and freak if necessary. + * Added stress task + * rewrite_rescue now detects rescue with multiple arguments. + +* 2 bug fixes: + + * Fixed dstr/dregex/d* roundtripping problem + * Fixed up call arg processing to be more correct and to work with the new sexp form + +=== 1.2.4 / 2009-08-14 + +* 2 bug fixes: + + * Fixed all doco to use ruby_praser + * Fixed bin/r2r_show to use ruby_parser. oops + +=== 1.2.3 / 2009-06-23 + +* 4 minor enhancements: + + * Overhauled 4-generation tests to use RubyParser. Much cleaner + * Removed last of ParseTree. Fully switched to RubyParser. + * Switched to minitest + * Updated Rakefile to new hoe capabilities + +=== 1.2.2 / 2009-01-20 + +* 3 minor enhancements: + + * Added -s to display sexp before printing r2r + * Added a bunch of backslash and masgn tests. + * Refactored tests. + +* 4 bug fixes: + + * Fixed iters to deal with empty bodies. + * Fixed process_call for a number of cases incl [], []=, and args processing. + * Fixed process_hash to always generate braces if in arglist. + * Switched process_alias to producing alias again, needed for globals. + +=== 1.2.1 / 2008-11-04 + +* 1 bug fix: + + * Don't freak out and die if passed a c function defn. stupid rails. + +=== 1.2.0 / 2008-10-22 + +* 2 minor enhancements: + + * Removed all PT dependent code to PT project (see parse_tree_extensions.rb). + * Revamped. Got working with new unified ruby output. Much much cleaner. + +=== 1.1.9 / 2008-06-09 + +* 5 minor enhancements: + + * Added more defensive programming in the tests to make it work with 1.9 and rubinius better. + * Converted r2r_show to more plain parse style, no more discover_new_classes. + * Made Proc#to_sexp and #to_ruby more resiliant. + * Started to work on fallback to ruby_parser code. Should prolly do flog first. + * Updated rakefile and readme format for hoe. Much cleaner! + +* 6 bug fixes: + + * Added 1.9 fixes. + * Added code to tests to isolate rubyinline builds. + * Fixed miniunit-deprecated assertions + * Fixes for const2/3, esp in class names + * Renamed ProcStoreTmp#name to #new_name. dur. + * Skip proc tests in 1.9 since they require ParseTree. + +=== 1.1.8 / 2007-08-21 + +* 6 minor enhancements: + + * Added super awesome .autotest file. YAY! + * Removed nil.method_missing... too many ppl bitching about it. + * Renamed RubyToRuby (the class name) to Ruby2Ruby. + * Restructured self-translation tests so they were friendlier when dying. + * Strings are now always one line long only. + * Fully in sync with ParseTree and ruby_parser. + +* 2 bug fixes: + + * Fixed a number of issues/bugs discovered via ruby_parser. + * Cleaned out some dead code and hacks we don't need anymore. + +=== 1.1.7 / 2007-08-21 + +* 2 major enhancements: + + * Switched to ParseTree's UnifiedRuby... much much cleaner now! + * Made test_ruby2ruby MUCH more rigorous with circular testing. + +* 5 minor enhancements: + + * Add r2r_show command like parse_tree_show. + * Add parens for :block nodes as appropriate. May be overzealous. + * Make SexpAny work with #==. + * Removed calls to processor_stack / caller in favor of self.context. + * Some style differences, eschew rescue. + +* 6 bug fixes: + + * Fix R2R bug with masgn/argscat. + * Fixed a bug with new resbody unification. + * Fixes for changes to pt_testcase. + * Fixes the rest of the tests under strict sexp checking. + * Fixed some circular bugs, mostly by hacking them out, wrt operator precidence. + * Fixed trinary operator. + +=== 1.1.6 / 2007-06-05 + +* 2 minor enhancements: + + * Extended tests for dstr/dsym/drgx to test against embedded slashes and quotes. + * Updated for dasgn_curr changes to PT. + +* 2 bug fixes: + + * Fixed a bug with begin/rescue/ensure. + * Fixed argscat and blockpass bug. blah(42, *args, &block) handled. + +=== 1.1.5 / 2007-02-13 + +* 3 minor enhancements: + + * Can now heckle ActiveRecord::Base in full. + * Cleaned up 1-liner generating code. + * Made clean/simple rescues 1-liners. + +* 7 bug fixes: + + * Finally got the rest of block_pass working. + * Fixed block_pass on procs in iters. UGH! + * Fixed attrasgn in masgn. + * Fixed splat in masgn. + * Fixed unary/prefix methods. + * Fixed attrasgn for []= where there were multiple args inside []. + * Fixed a couple resbody bugs. + +=== 1.1.4 / 2007-01-15 + +* 4 minor enhancements: + + * Added some extra rewriting code and tests for various bmethods. Ugh. + * Added support for splatted block args. + * Refactored class/module and dsym/dstr. + * Short if/unless statements are now post-conditional expressions. + +* 4 bug fixes: + + * Finally fixed eric's nebulous proc code-in-goalposts bug. + * Fixed dasgn_curr so block's dasgn vars decl goes away (bug 7420). + * Fixed dmethod. I think the tests were bogus before. + * Fixed improper end in method rescues (bug 7396). + +=== 1.1.3 / 2006-12-20 + +* 1 minor enhancement + + * Unit tests do self-translation and retesting for 3 generations! Solid. BAM! + +* 1 bug fixes + + * iasgn inside masgn was totally borked in ruby2ruby. + +=== 1.1.2 / 2006-12-19 + +* 2 minor enhancements + + * Improved []= and [] to be more idiomatic. + * Support for nested whens (from when case has no expression). + +* 3 bug fixes + + * Fixed case output when there is no case expression. + * NEARLY have RubyToRuby self-cloning and passing tests again. + * Minor cleanup + +=== 1.1.1 / 2006-11-13 + +* 3 bug fixes + + * Fixed procs + * Cleaned return when no return values. + * Rewrote process_if. No more elsif but no more bugs. :) + +=== 1.1.0 / 2006-10-11 + +* 2 major enhancements + + * Released separately from ZenHacks. + * Major overhaul/audit from the new ParseTree test infrastructure. Very complete now. diff -Nru ruby-ruby2ruby-2.3.0/History.txt ruby-ruby2ruby-2.4.1/History.txt --- ruby-ruby2ruby-2.3.0/History.txt 2016-03-30 23:22:41.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/History.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,371 +0,0 @@ -=== 2.3.0 / 2016-02-18 - -* 3 minor enhancements: - - * Added support for safe navigation/lonely operator. (presidentbeef) - * Expanded tests for 2.3 support - * Support safe attrasgn. (presidentbeef). - -=== 2.2.0 / 2015-05-27 - -* 1 minor enhancement: - - * Normalized block arg goalposts (always there unless arg slot == 0). - -=== 2.1.4 / 2015-04-13 - -* 1 minor enhancement: - - * Wrap fewer hash values in parentheses. (jaredbeck) - -* 1 bug fix: - - * Fixed handling of kwsplat args. - -=== 2.1.3 / 2014-09-26 - -* 1 bug fix: - - * Fixed handling of kwargs. (joenas) - -=== 2.1.2 / 2014-08-28 - -* 1 bug fix: - - * Fixed readme to point out that deep_clone may be needed. (heathd) - -=== 2.1.1 / 2014-06-09 - -* 1 bug fix: - - * Moved Regexp::CODES out of guard on ::ENC_NONE. (presidentbeef) - -=== 2.1.0 / 2014-04-23 - -* 4 minor enhancements: - - * Don't indent defn body extra if it has a top-level rescue. - * Don't indent defn body until fully processed. - * Don't use simple rescue form if resbody is a return (statement keyword). (eyberg) - * Remove superfluous begin/end for top-level defn rescue. - -=== 2.0.8 / 2014-03-24 - -* 1 bug fix: - - * 2.0/2.1: Fixed support for **kwsplat. (troessner) - -=== 2.0.7 / 2013-12-13 - -* 4 minor enhancements: - - * Add != to list of binary operators. (camertron) *le sigh* - * Clean out cruft from process_masgn that I can't reproduce anymore. - * Extend process_args to deal with masgn (eg: a.b { |(c, d)| ... }). - * Extend process_masgn to deal with both sexps and var lists. - -* 1 bug fix: - - * Ensure proper parens on rescue subexpressions. (Bocete) - -=== 2.0.6 / 2013-06-20 - -* 2 bug fixes: - - * Fixed bug with complex rescue but short enough to trigger 1-liner. (Confusion) - * Fixed multiple expressions inside sclass - -=== 2.0.5 / 2013-04-25 - -* 2 bug fixes: - - * Fixed attrasgn w/ multiple keys: a[x, y] = z. (derula) - * Fixed error w/ attr_* detection when more than 1 ivar/iasgn exist in body. - -=== 2.0.4 / 2013-03-28 - -* 1 bug fix: - - * Fixed attr_* generators in cases where the body isn't idiomatic. (robertfeldt) - -=== 2.0.3 / 2013-02-07 - -* 2 minor enhancements: - - * 1.9: Added support for ! call to go back to (not ...). - * 2nd and 3rd order testing now uses RubyPraser.for_current_ruby for maximal carnage. - -* 1 bug fix: - - * On failure (eg ruby 2.0), fall back to compound RubyParser instance for 2nd & 3rd order testing - -=== 2.0.2 / 2013-01-16 - -* 1 minor enhancement: - - * Updated to ruby_parser 3.1 and up - -=== 2.0.1 / 2012-11-02 - -* 1 bug fix: - - * Fixed dependency on alpha ruby_parser. *sigh* - -=== 2.0.0 / 2012-11-02 - -* 1 minor enhancement: - - * Only do phase 1 testing if $SIMPLE=1. - -* 1 bug fix: - - * Fixed block args processing for RP 3.0 sexp changes - -=== 2.0.0.b1 / 2012-07-27 - -* 4 major enhancements: - - * Made it work without arglist in call. - * Made it work without scope/block in class/module/defn/defs. - * Removed block from resbody - * Removed block from when node - -* 4 minor enhancements: - - * Added debug task to help isolate an error - * Empty hash is now a proper {} - * Refactored and added finish method. - * Switched to new Ruby18Parser to avoid deprecation warnings - -* 4 bug fixes: - - * Fixed call with empty hash arg. (neilconway) - * OMG WTF... removed long decrepit ParseTree dependency - * Removed isolate/rake require to reduce minimum bootstrap to hoe + rake + rake install_plugins (*2) - * Skip 1.9 tests for now. - -=== 1.3.1 / 2011-09-22 - -* 1 minor enhancement: - - * Added parenthesize to add parens in certain contexts. - -* 10 bug fixes: - - * Add newline to 'do nothing' comment in a block... seems contrived. (andreacampi) - * Binary operations not work properly with some complex statements. (smorss) - * Fixed if statements with no body (smorss) - * Fixed logic for call with hash args in various locations (smorss) - * Fixed match3 on an assignment. (smorss) - * Fixed multiple nested rescue/ensure exprs (larsch) - * Fixed process_alias to parenthesize (smorss) - * Fixed process_and to parenthenize only when it makes sense. - * Fixed rescue with 2+ statements in resbody (smorss) - * Regexps with options other than /o were not showing flags. (smorss) - -=== 1.3.0 / 2011-09-01 - -* 1 minor enhancement: - - * output comments for class and method definitions. (pythonic) - -=== 1.2.5 / 2010-09-01 - -* 4 minor enhancements: - - * Added braces to hash args surrounded if in a binary method call. - * Added rewrite_resbody to double check structure and freak if necessary. - * Added stress task - * rewrite_rescue now detects rescue with multiple arguments. - -* 2 bug fixes: - - * Fixed dstr/dregex/d* roundtripping problem - * Fixed up call arg processing to be more correct and to work with the new sexp form - -=== 1.2.4 / 2009-08-14 - -* 2 bug fixes: - - * Fixed all doco to use ruby_praser - * Fixed bin/r2r_show to use ruby_parser. oops - -=== 1.2.3 / 2009-06-23 - -* 4 minor enhancements: - - * Overhauled 4-generation tests to use RubyParser. Much cleaner - * Removed last of ParseTree. Fully switched to RubyParser. - * Switched to minitest - * Updated Rakefile to new hoe capabilities - -=== 1.2.2 / 2009-01-20 - -* 3 minor enhancements: - - * Added -s to display sexp before printing r2r - * Added a bunch of backslash and masgn tests. - * Refactored tests. - -* 4 bug fixes: - - * Fixed iters to deal with empty bodies. - * Fixed process_call for a number of cases incl [], []=, and args processing. - * Fixed process_hash to always generate braces if in arglist. - * Switched process_alias to producing alias again, needed for globals. - -=== 1.2.1 / 2008-11-04 - -* 1 bug fix: - - * Don't freak out and die if passed a c function defn. stupid rails. - -=== 1.2.0 / 2008-10-22 - -* 2 minor enhancements: - - * Removed all PT dependent code to PT project (see parse_tree_extensions.rb). - * Revamped. Got working with new unified ruby output. Much much cleaner. - -=== 1.1.9 / 2008-06-09 - -* 5 minor enhancements: - - * Added more defensive programming in the tests to make it work with 1.9 and rubinius better. - * Converted r2r_show to more plain parse style, no more discover_new_classes. - * Made Proc#to_sexp and #to_ruby more resiliant. - * Started to work on fallback to ruby_parser code. Should prolly do flog first. - * Updated rakefile and readme format for hoe. Much cleaner! - -* 6 bug fixes: - - * Added 1.9 fixes. - * Added code to tests to isolate rubyinline builds. - * Fixed miniunit-deprecated assertions - * Fixes for const2/3, esp in class names - * Renamed ProcStoreTmp#name to #new_name. dur. - * Skip proc tests in 1.9 since they require ParseTree. - -=== 1.1.8 / 2007-08-21 - -* 6 minor enhancements: - - * Added super awesome .autotest file. YAY! - * Removed nil.method_missing... too many ppl bitching about it. - * Renamed RubyToRuby (the class name) to Ruby2Ruby. - * Restructured self-translation tests so they were friendlier when dying. - * Strings are now always one line long only. - * Fully in sync with ParseTree and ruby_parser. - -* 2 bug fixes: - - * Fixed a number of issues/bugs discovered via ruby_parser. - * Cleaned out some dead code and hacks we don't need anymore. - -=== 1.1.7 / 2007-08-21 - -* 2 major enhancements: - - * Switched to ParseTree's UnifiedRuby... much much cleaner now! - * Made test_ruby2ruby MUCH more rigorous with circular testing. - -* 5 minor enhancements: - - * Add r2r_show command like parse_tree_show. - * Add parens for :block nodes as appropriate. May be overzealous. - * Make SexpAny work with #==. - * Removed calls to processor_stack / caller in favor of self.context. - * Some style differences, eschew rescue. - -* 6 bug fixes: - - * Fix R2R bug with masgn/argscat. - * Fixed a bug with new resbody unification. - * Fixes for changes to pt_testcase. - * Fixes the rest of the tests under strict sexp checking. - * Fixed some circular bugs, mostly by hacking them out, wrt operator precidence. - * Fixed trinary operator. - -=== 1.1.6 / 2007-06-05 - -* 2 minor enhancements: - - * Extended tests for dstr/dsym/drgx to test against embedded slashes and quotes. - * Updated for dasgn_curr changes to PT. - -* 2 bug fixes: - - * Fixed a bug with begin/rescue/ensure. - * Fixed argscat and blockpass bug. blah(42, *args, &block) handled. - -=== 1.1.5 / 2007-02-13 - -* 3 minor enhancements: - - * Can now heckle ActiveRecord::Base in full. - * Cleaned up 1-liner generating code. - * Made clean/simple rescues 1-liners. - -* 7 bug fixes: - - * Finally got the rest of block_pass working. - * Fixed block_pass on procs in iters. UGH! - * Fixed attrasgn in masgn. - * Fixed splat in masgn. - * Fixed unary/prefix methods. - * Fixed attrasgn for []= where there were multiple args inside []. - * Fixed a couple resbody bugs. - -=== 1.1.4 / 2007-01-15 - -* 4 minor enhancements: - - * Added some extra rewriting code and tests for various bmethods. Ugh. - * Added support for splatted block args. - * Refactored class/module and dsym/dstr. - * Short if/unless statements are now post-conditional expressions. - -* 4 bug fixes: - - * Finally fixed eric's nebulous proc code-in-goalposts bug. - * Fixed dasgn_curr so block's dasgn vars decl goes away (bug 7420). - * Fixed dmethod. I think the tests were bogus before. - * Fixed improper end in method rescues (bug 7396). - -=== 1.1.3 / 2006-12-20 - -* 1 minor enhancement - - * Unit tests do self-translation and retesting for 3 generations! Solid. BAM! - -* 1 bug fixes - - * iasgn inside masgn was totally borked in ruby2ruby. - -=== 1.1.2 / 2006-12-19 - -* 2 minor enhancements - - * Improved []= and [] to be more idiomatic. - * Support for nested whens (from when case has no expression). - -* 3 bug fixes - - * Fixed case output when there is no case expression. - * NEARLY have RubyToRuby self-cloning and passing tests again. - * Minor cleanup - -=== 1.1.1 / 2006-11-13 - -* 3 bug fixes - - * Fixed procs - * Cleaned return when no return values. - * Rewrote process_if. No more elsif but no more bugs. :) - -=== 1.1.0 / 2006-10-11 - -* 2 major enhancements - - * Released separately from ZenHacks. - * Major overhaul/audit from the new ParseTree test infrastructure. Very complete now. diff -Nru ruby-ruby2ruby-2.3.0/lib/ruby2ruby.rb ruby-ruby2ruby-2.4.1/lib/ruby2ruby.rb --- ruby-ruby2ruby-2.3.0/lib/ruby2ruby.rb 2016-03-30 23:22:41.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/lib/ruby2ruby.rb 2018-07-10 14:01:22.000000000 +0000 @@ -31,13 +31,13 @@ # Generate ruby code from a sexp. class Ruby2Ruby < SexpProcessor - VERSION = "2.3.0" # :nodoc: + VERSION = "2.4.1" # :nodoc: # cutoff for one-liners LINE_LENGTH = 78 # binary operation messages - BINARY = [:<=>, :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%, :<<, :>>, :**, :'!='] + BINARY = [:<=>, :==, :<, :>, :<=, :>=, :-, :+, :*, :/, :%, :<<, :>>, :**, :'!=', :^, :|, :&] ## # Nodes that represent assignment and probably need () around them. @@ -50,6 +50,7 @@ :flip3, :lasgn, :masgn, + :match3, :attrasgn, :op_asgn1, :op_asgn2, @@ -81,7 +82,7 @@ def initialize # :nodoc: super @indent = " " - self.auto_shift_type = true + self.require_empty = false self.strict = true self.expected = String @@ -93,71 +94,72 @@ ############################################################ # Processors - def process_alias(exp) # :nodoc: - parenthesize "alias #{process(exp.shift)} #{process(exp.shift)}" + def process_alias exp # :nodoc: + _, lhs, rhs = exp + + parenthesize "alias #{process lhs} #{process rhs}" end - def process_and(exp) # :nodoc: - parenthesize "#{process exp.shift} and #{process exp.shift}" + def process_and exp # :nodoc: + _, lhs, rhs = exp + + parenthesize "#{process lhs} and #{process rhs}" end - def process_arglist(exp) # custom made node # :nodoc: - code = [] - until exp.empty? do - arg = exp.shift - to_wrap = arg.first == :rescue - arg_code = process arg - code << (to_wrap ? "(#{arg_code})" : arg_code) - end - code.join ', ' + def process_arglist exp # custom made node # :nodoc: + _, *args = exp + + args.map { |arg| + code = process arg + arg.sexp_type == :rescue ? "(#{code})" : code + }.join ", " end - def process_args(exp) # :nodoc: - args = [] + def process_args exp # :nodoc: + _, *args = exp - until exp.empty? do - arg = exp.shift + args = args.map { |arg| case arg when Symbol then - args << arg + arg when Sexp then - case arg.first + case arg.sexp_type when :lasgn then - args << process(arg) + process(arg) when :masgn then - args << process(arg) + process(arg) when :kwarg then _, k, v = arg - args << "#{k}: #{process v}" + "#{k}: #{process v}" else raise "unknown arg type #{arg.first.inspect}" end else raise "unknown arg type #{arg.inspect}" end - end + } "(#{args.join ', '})" end - def process_array(exp) # :nodoc: - "[#{process_arglist(exp)}]" + def process_array exp # :nodoc: + "[#{process_arglist exp}]" end - def process_attrasgn(exp) # :nodoc: - receiver = process exp.shift - name = exp.shift - rhs = exp.pop - args = s(:array, *exp) - exp.clear + def process_attrasgn exp # :nodoc: + _, recv, name, *args = exp + + rhs = args.pop + args = s(:array, *args) + receiver = process recv case name when :[]= then args = process args "#{receiver}#{args} = #{process rhs}" else - raise "dunno what to do: #{args.inspect}" unless args.size == 1 # s(:array) - name = name.to_s.sub(/=$/, '') + raise "dunno what to do: #{args.inspect}" if args.size != 1 # s(:array) + name = name.to_s.chomp "=" if rhs && rhs != s(:arglist) then "#{receiver}.#{name} = #{process(rhs)}" else @@ -166,51 +168,54 @@ end end - def process_back_ref(exp) # :nodoc: - "$#{exp.shift}" + def process_back_ref exp # :nodoc: + _, n = exp + + "$#{n}" end # TODO: figure out how to do rescue and ensure ENTIRELY w/o begin - def process_begin(exp) # :nodoc: - code = [] - code << "begin" - until exp.empty? - src = process(exp.shift) - src = indent(src) unless src =~ /(^|\n)(rescue|ensure)/ # ensure no level 0 rescues - code << src - end - code << "end" - return code.join("\n") + def process_begin exp # :nodoc: + _, *rest = exp + + code = rest.map { |sexp| + src = process sexp + src = indent src unless src =~ /(^|\n)(rescue|ensure)/ # ensure no level 0 rescues + src + } + code.unshift "begin" + code.push "end" + + code.join "\n" end - def process_block(exp) # :nodoc: - result = [] + def process_block exp # :nodoc: + _, *body = exp - exp << nil if exp.empty? - until exp.empty? do - code = exp.shift - if code.nil? or code.first == :nil then - result << "# do nothing\n" - else - result << process(code) - end - end + result = body.map { |sexp| + process sexp + } + result << "# do nothing\n" if result.empty? result = parenthesize result.join "\n" result += "\n" unless result.start_with? "(" - return result + result end def process_block_pass exp # :nodoc: - raise "huh?: #{exp.inspect}" if exp.size > 1 + raise "huh?: #{exp.inspect}" if exp.size > 2 - "&#{process exp.shift}" + _, sexp = exp + + "&#{process sexp}" end - def process_break(exp) # :nodoc: - val = exp.empty? ? nil : process(exp.shift) - # HACK "break" + (val ? " #{val}" : "") + def process_break exp # :nodoc: + _, arg = exp + + val = process arg + if val then "break #{val}" else @@ -219,43 +224,47 @@ end def process_call(exp, safe_call = false) # :nodoc: - receiver_node_type = exp.first.nil? ? nil : exp.first.first - receiver = process exp.shift + _, recv, name, *args = exp + + receiver_node_type = recv && recv.sexp_type + receiver = process recv receiver = "(#{receiver})" if ASSIGN_NODES.include? receiver_node_type - name = exp.shift - args = [] + # args = [] # this allows us to do both old and new sexp forms: - exp.push(*exp.pop[1..-1]) if exp.size == 1 && exp.first.first == :arglist + # exp.push(*exp.pop[1..-1]) if exp.size == 1 && exp.first.first == :arglist @calls.push name in_context :arglist do - until exp.empty? do - arg_type = exp.first.sexp_type - is_empty_hash = (exp.first == s(:hash)) - arg = process exp.shift + max = args.size-1 + args = args.map.with_index { |arg, i| + arg_type = arg.sexp_type + is_empty_hash = arg == s(:hash) + arg = process arg next if arg.empty? strip_hash = (arg_type == :hash and not BINARY.include? name and not is_empty_hash and - (exp.empty? or exp.first.sexp_type == :splat)) + (i == max or args[i+1].sexp_type == :splat)) wrap_arg = Ruby2Ruby::ASSIGN_NODES.include? arg_type arg = arg[2..-3] if strip_hash arg = "(#{arg})" if wrap_arg - args << arg - end + arg + }.compact end case name when *BINARY then if safe_call "#{receiver}&.#{name}(#{args.join(', ')})" + elsif args.length > 1 + "#{receiver}.#{name}(#{args.join(', ')})" else "(#{receiver} #{name} #{args.join(', ')})" end @@ -284,159 +293,162 @@ @calls.pop end - def process_safe_call(exp) # :nodoc: - process_call(exp, :safe) + def process_safe_call exp # :nodoc: + process_call exp, :safe end - def process_case(exp) # :nodoc: + def process_case exp # :nodoc: + _, expr, *rest = exp + result = [] - expr = process exp.shift + + expr = process expr + if expr then result << "case #{expr}" else result << "case" end - until exp.empty? - pt = exp.shift - if pt and pt.first == :when - result << "#{process(pt)}" + + result.concat rest.map { |pt| + if pt and pt.sexp_type == :when + "#{process pt}" else - code = indent(process(pt)) + code = indent process pt code = indent("# do nothing") if code =~ /^\s*$/ - result << "else\n#{code}" + "else\n#{code}" end - end + } + result << "end" - result.join("\n") + + result.join "\n" end - def process_cdecl(exp) # :nodoc: - lhs = exp.shift + def process_cdecl exp # :nodoc: + _, lhs, rhs = exp lhs = process lhs if Sexp === lhs - unless exp.empty? then - rhs = process(exp.shift) + if rhs then + rhs = process rhs "#{lhs} = #{rhs}" else lhs.to_s end end - def process_class(exp) # :nodoc: + def process_class exp # :nodoc: "#{exp.comments}class #{util_module_or_class(exp, true)}" end - def process_colon2(exp) # :nodoc: - "#{process(exp.shift)}::#{exp.shift}" + def process_colon2 exp # :nodoc: + _, lhs, rhs = exp + + "#{process lhs}::#{rhs}" end - def process_colon3(exp) # :nodoc: - "::#{exp.shift}" + def process_colon3 exp # :nodoc: + _, rhs = exp + + "::#{rhs}" end - def process_const(exp) # :nodoc: - exp.shift.to_s + def process_const exp # :nodoc: + _, name = exp + + name.to_s end - def process_cvar(exp) # :nodoc: - "#{exp.shift}" + def process_cvar exp # :nodoc: + _, name = exp + + name.to_s end - def process_cvasgn(exp) # :nodoc: - "#{exp.shift} = #{process(exp.shift)}" + def process_cvasgn exp # :nodoc: + _, lhs, rhs = exp + + "#{lhs} = #{process rhs}" end - def process_cvdecl(exp) # :nodoc: - "#{exp.shift} = #{process(exp.shift)}" + def process_cvdecl exp # :nodoc: + _, lhs, rhs = exp + + "#{lhs} = #{process rhs}" end - def process_defined(exp) # :nodoc: - "defined? #{process(exp.shift)}" + def process_defined exp # :nodoc: + _, rhs = exp + "defined? #{process rhs}" end def process_defn(exp) # :nodoc: - type1 = exp[1].first - type2 = exp[2].first rescue nil - expect = [:ivar, :iasgn, :attrset] - - # s(name, args, ivar|iasgn|attrset) - if exp.size == 3 and type1 == :args and expect.include? type2 then - name = exp.first # don't shift in case we pass through - case type2 - when :ivar then - ivar_name = exp.ivar.last - - meth_name = ivar_name.to_s[1..-1].to_sym - expected = s(meth_name, s(:args), s(:ivar, ivar_name)) - - if exp == expected then - exp.clear - return "attr_reader #{name.inspect}" - end - when :attrset then - # TODO: deprecate? this is a PT relic - exp.clear - return "attr_writer :#{name.to_s[0..-2]}" - when :iasgn then - ivar_name = exp.iasgn[1] - meth_name = "#{ivar_name.to_s[1..-1]}=".to_sym - arg_name = exp.args.last - expected = s(meth_name, s(:args, arg_name), - s(:iasgn, ivar_name, s(:lvar, arg_name))) - - if exp == expected then - exp.clear - return "attr_writer :#{name.to_s[0..-2]}" - end - else - raise "Unknown defn type: #{exp.inspect}" - end - end + _, name, args, *body = exp comm = exp.comments - name = exp.shift - args = process exp.shift + args = process args args = "" if args == "()" - exp.shift if exp == s(s(:nil)) # empty it out of a default nil expression + body = s() if body == s(s(:nil)) # empty it out of a default nil expression - # REFACTOR: use process_block but get it happier wrt parenthesize - body = [] - until exp.empty? do - body << process(exp.shift) - end + # s(:defn, name, args, ivar|iasgn) + case exp + when s{ s(:defn, atom, t(:args), s(:ivar, atom)) } then # TODO: atom -> _ + _, ivar = body.first + ivar = ivar.to_s[1..-1] # remove leading @ + reader = name.to_s + return "attr_reader #{name.inspect}" if reader == ivar + when s{ s(:defn, atom, t(:args), s(:iasgn, atom, s(:lvar, atom))) } then + _, ivar, _val = body.first + ivar = ivar.to_s[1..-1] # remove leading @ + reader = name.to_s.chomp "=" + return "attr_writer :#{reader}" if reader == ivar + end + + body = body.map { |ssexp| + process ssexp + } + + simple = body.size <= 1 body << "# do nothing" if body.empty? body = body.join("\n") body = body.lines.to_a[1..-2].join("\n") if - body =~ /^\Abegin/ && body =~ /^end\z/ - body = indent(body) unless body =~ /(^|\n)rescue/ + simple && body =~ /^\Abegin/ && body =~ /^end\z/ + body = indent(body) unless simple && body =~ /(^|\n)rescue/ return "#{comm}def #{name}#{args}\n#{body}\nend".gsub(/\n\s*\n+/, "\n") end - def process_defs(exp) # :nodoc: - lhs = exp.shift - var = [:self, :cvar, :dvar, :ivar, :gvar, :lvar].include? lhs.first - name = exp.shift + def process_defs exp # :nodoc: + _, lhs, name, args, *body = exp + var = [:self, :cvar, :dvar, :ivar, :gvar, :lvar].include? lhs.sexp_type - lhs = process(lhs) + lhs = process lhs lhs = "(#{lhs})" unless var - exp.unshift "#{lhs}.#{name}" - process_defn(exp) + name = "#{lhs}.#{name}" + + process_defn s(:defn, name, args, *body) end def process_dot2(exp) # :nodoc: - "(#{process exp.shift}..#{process exp.shift})" + _, lhs, rhs = exp + + "(#{process lhs}..#{process rhs})" end def process_dot3(exp) # :nodoc: - "(#{process exp.shift}...#{process exp.shift})" + _, lhs, rhs = exp + + "(#{process lhs}...#{process rhs})" end - def process_dregx(exp) # :nodoc: - options = re_opt exp.pop if Fixnum === exp.last - "/" << util_dthing(:dregx, exp) << "/#{options}" + def process_dregx exp # :nodoc: + _, str, *rest = exp + + options = re_opt rest.pop if Integer === rest.last + + "/" << util_dthing(:dregx, s(:dregx, str, *rest)) << "/#{options}" end def process_dregx_once(exp) # :nodoc: @@ -456,8 +468,9 @@ end def process_ensure(exp) # :nodoc: - body = process exp.shift - ens = exp.shift + _, body, ens = exp + + body = process body ens = nil if ens == s(:nil) ens = process(ens) || "# do nothing" ens = "begin\n#{ens}\nend\n" if ens =~ /(^|\n)rescue/ @@ -468,80 +481,91 @@ return "#{body}\nensure\n#{indent ens}" end - def process_evstr(exp) # :nodoc: - exp.empty? ? '' : process(exp.shift) + def process_evstr exp # :nodoc: + _, x = exp + + x ? process(x) : "" end - def process_false(exp) # :nodoc: + def process_false exp # :nodoc: "false" end - def process_flip2(exp) # :nodoc: - "#{process(exp.shift)}..#{process(exp.shift)}" + def process_flip2 exp # :nodoc: + _, lhs, rhs = exp + + "#{process lhs}..#{process rhs}" end - def process_flip3(exp) # :nodoc: - "#{process(exp.shift)}...#{process(exp.shift)}" + def process_flip3 exp # :nodoc: + _, lhs, rhs = exp + + "#{process lhs}...#{process rhs}" end - def process_for(exp) # :nodoc: - recv = process exp.shift - iter = process exp.shift - body = exp.empty? ? nil : process(exp.shift) + def process_for exp # :nodoc: + _, recv, iter, body = exp + + recv = process recv + iter = process iter + body = process(body) || "# do nothing" result = ["for #{iter} in #{recv} do"] - result << indent(body ? body : "# do nothing") + result << indent(body) result << "end" - result.join("\n") + result.join "\n" end - def process_gasgn(exp) # :nodoc: - process_iasgn(exp) + def process_gasgn exp # :nodoc: + process_iasgn exp end - def process_gvar(exp) # :nodoc: - return exp.shift.to_s + def process_gvar exp # :nodoc: + _, name = exp + + name.to_s end def process_hash(exp) # :nodoc: + _, *pairs = exp + result = [] - until exp.empty? - s = exp.shift - t = s.sexp_type - lhs = process s - - case t - when :kwsplat then - result << lhs + result = pairs.each_slice(2).map { |k, v| + if k.sexp_type == :kwsplat then + "%s" % process(k) else - rhs = exp.shift - t = rhs.first - rhs = process rhs + t = v.sexp_type + + lhs = process k + rhs = process v rhs = "(#{rhs})" unless HASH_VAL_NO_PAREN.include? t - result << "#{lhs} => #{rhs}" + "%s => %s" % [lhs, rhs] end - end + } return result.empty? ? "{}" : "{ #{result.join(', ')} }" end def process_iasgn(exp) # :nodoc: - lhs = exp.shift - if exp.empty? then # part of an masgn + _, lhs, rhs = exp + + if rhs then + "#{lhs} = #{process rhs}" + else # part of an masgn lhs.to_s - else - "#{lhs} = #{process exp.shift}" end end def process_if(exp) # :nodoc: - expand = Ruby2Ruby::ASSIGN_NODES.include? exp.first.first - c = process exp.shift - t = process exp.shift - f = process exp.shift + _, c, t, f = exp + + expand = Ruby2Ruby::ASSIGN_NODES.include? c.sexp_type + c = process c + t = process t + f = process f c = "(#{c.chomp})" if c =~ /\n/ @@ -574,9 +598,10 @@ end def process_iter(exp) # :nodoc: - iter = process exp.shift - args = exp.shift - body = exp.empty? ? nil : process(exp.shift) + _, iter, args, body = exp + + iter = process iter + body = process body if body args = case args when 0 then @@ -619,21 +644,25 @@ end def process_ivar(exp) # :nodoc: - exp.shift.to_s + _, name = exp + name.to_s end def process_kwsplat(exp) - "**#{process exp.shift}" + _, kw = exp + "**#{process kw}" end def process_lasgn(exp) # :nodoc: - s = "#{exp.shift}" - s += " = #{process exp.shift}" unless exp.empty? + _, name, value = exp + + s = "#{name}" + s += " = #{process value}" if value s end - def process_lit(exp) # :nodoc: - obj = exp.shift + def process_lit exp # :nodoc: + _, obj = exp case obj when Range then "(#{obj.inspect})" @@ -643,23 +672,25 @@ end def process_lvar(exp) # :nodoc: - exp.shift.to_s + _, name = exp + name.to_s end def process_masgn(exp) # :nodoc: # s(:masgn, s(:array, s(:lasgn, :var), ...), s(:to_ary, , ...)) # s(:iter, , s(:args, s(:masgn, :a, :b)), ) + _, *exp = exp # HACK + case exp.first when Sexp then - lhs = exp.shift - rhs = exp.empty? ? nil : exp.shift + lhs, rhs = exp - case lhs.first + case lhs.sexp_type when :array then - lhs.shift # node type + _, *lhs = lhs # HACK lhs = lhs.map do |l| - case l.first + case l.sexp_type when :masgn then "(#{process(l)})" else @@ -670,8 +701,8 @@ raise "no clue: #{lhs.inspect}" end - unless rhs.nil? then - t = rhs.first + if rhs then + t = rhs.sexp_type rhs = process rhs rhs = rhs[1..-2] if t == :array # FIX: bad? I dunno return "#{lhs.join(", ")} = #{rhs}" @@ -687,20 +718,28 @@ end end - def process_match(exp) # :nodoc: - "#{process(exp.shift)}" + def process_match exp # :nodoc: + _, rhs = exp + + "#{process rhs}" end - def process_match2(exp) # :nodoc: - lhs = process(exp.shift) - rhs = process(exp.shift) + def process_match2 exp # :nodoc: + # s(:match2, s(:lit, /x/), s(:str, "blah")) + _, lhs, rhs = exp + + lhs = process lhs + rhs = process rhs + "#{lhs} =~ #{rhs}" end - def process_match3(exp) # :nodoc: - rhs = process(exp.shift) - left_type = exp.first.sexp_type - lhs = process(exp.shift) + def process_match3 exp # :nodoc: + _, rhs, lhs = exp # yes, backwards + + left_type = lhs.sexp_type + lhs = process lhs + rhs = process rhs if ASSIGN_NODES.include? left_type then "(#{lhs}) =~ #{rhs}" @@ -714,7 +753,9 @@ end def process_next(exp) # :nodoc: - val = exp.empty? ? nil : process(exp.shift) + _, rhs = exp + + val = rhs && process(rhs) # maybe push down into if and test rhs? if val then "next #{val}" else @@ -727,30 +768,43 @@ end def process_not(exp) # :nodoc: - "(not #{process exp.shift})" + _, sexp = exp + "(not #{process sexp})" end def process_nth_ref(exp) # :nodoc: - "$#{exp.shift}" + _, n = exp + "$#{n}" + end + + def process_op_asgn exp # :nodoc: + # [[:lvar, :x], [:call, nil, :z, [:lit, 1]], :y, :"||"] + _, lhs, rhs, index, op = exp + + lhs = process lhs + rhs = process rhs + + "#{lhs}.#{index} #{op}= #{rhs}" end def process_op_asgn1(exp) # :nodoc: # [[:lvar, :b], [:arglist, [:lit, 1]], :"||", [:lit, 10]] - lhs = process(exp.shift) - index = process(exp.shift) - msg = exp.shift - rhs = process(exp.shift) + _, lhs, index, msg, rhs = exp + + lhs = process lhs + index = process index + rhs = process rhs "#{lhs}[#{index}] #{msg}= #{rhs}" end - def process_op_asgn2(exp) # :nodoc: + def process_op_asgn2 exp # :nodoc: # [[:lvar, :c], :var=, :"||", [:lit, 20]] - lhs = process(exp.shift) - index = exp.shift.to_s[0..-2] - msg = exp.shift + _, lhs, index, msg, rhs = exp - rhs = process(exp.shift) + lhs = process lhs + index = index.to_s[0..-2] + rhs = process rhs "#{lhs}.#{index} #{msg}= #{rhs}" end @@ -758,19 +812,21 @@ def process_op_asgn_and(exp) # :nodoc: # a &&= 1 # [[:lvar, :a], [:lasgn, :a, [:lit, 1]]] - exp.shift - process(exp.shift).sub(/\=/, '&&=') + _, _lhs, rhs = exp + process(rhs).sub(/\=/, '&&=') end def process_op_asgn_or(exp) # :nodoc: # a ||= 1 # [[:lvar, :a], [:lasgn, :a, [:lit, 1]]] - exp.shift - process(exp.shift).sub(/\=/, '||=') + _, _lhs, rhs = exp + process(rhs).sub(/\=/, '||=') end def process_or(exp) # :nodoc: - "(#{process exp.shift} or #{process exp.shift})" + _, lhs, rhs = exp + + "(#{process lhs} or #{process rhs})" end def process_postexe(exp) # :nodoc: @@ -782,8 +838,13 @@ end def process_resbody exp # :nodoc: - args = exp.shift - body = finish(exp) + # s(:resbody, s(:array), s(:return, s(:str, "a"))) + _, args, *body = exp + + body = body.compact.map { |sexp| + process sexp + } + body << "# do nothing" if body.empty? name = args.lasgn true @@ -796,21 +857,25 @@ end def process_rescue exp # :nodoc: - body = process(exp.shift) unless exp.first.first == :resbody - els = process(exp.pop) unless exp.last.first == :resbody + _, *rest = exp + exp = nil + + body = process rest.shift unless rest.first.sexp_type == :resbody + els = process rest.pop unless rest.last && rest.last.sexp_type == :resbody body ||= "# do nothing" - simple = exp.size == 1 && exp.resbody.size <= 3 && - !exp.resbody.block && - !exp.resbody.return - - resbodies = [] - until exp.empty? do - resbody = exp.shift - simple &&= resbody[1] == s(:array) - simple &&= resbody[2] != nil && resbody[2].node_type != :block - resbodies << process(resbody) - end + + # TODO: I don't like this using method_missing, but I need to ensure tests + simple = rest.size == 1 && rest.first.size <= 3 && + !rest.first.block && + !rest.first.return + + resbodies = rest.map { |resbody| + _, rb_args, rb_body, *rb_rest = resbody + simple &&= rb_args == s(:array) + simple &&= rb_rest.empty? && rb_body && rb_body.node_type != :block + process resbody + } if els then "#{indent body}\n#{resbodies.join("\n")}\nelse\n#{indent els}" @@ -826,36 +891,66 @@ "retry" end - def process_return(exp) # :nodoc: - # HACK return "return" + (exp.empty? ? "" : " #{process exp.shift}") + def process_return exp # :nodoc: + _, rhs = exp - if exp.empty? then - return "return" + unless rhs then + "return" else - return "return #{process exp.shift}" + rhs_type = rhs.sexp_type + rhs = process rhs + rhs = "(#{rhs})" if ASSIGN_NODES.include? rhs_type + "return #{rhs}" end end - def process_safe_attrasgn(exp) # :nodoc: - receiver = process exp.shift - name = exp.shift - rhs = exp.pop - args = exp.pop # should be nil - exp.clear + def process_safe_attrasgn exp # :nodoc: + _, receiver, name, *rest = exp + + receiver = process receiver + rhs = rest.pop + args = rest.pop # should be nil raise "dunno what to do: #{args.inspect}" if args name = name.to_s.sub(/=$/, '') if rhs && rhs != s(:arglist) then - "#{receiver}&.#{name} = #{process(rhs)}" + "#{receiver}&.#{name} = #{process rhs}" else raise "dunno what to do: #{rhs.inspect}" end end + def process_safe_op_asgn exp # :nodoc: + # [[:lvar, :x], [:call, nil, :z, [:lit, 1]], :y, :"||"] + _, lhs, rhs, index, op = exp + + lhs = process lhs + rhs = process rhs + + "#{lhs}&.#{index} #{op}= #{rhs}" + end + + def process_safe_op_asgn2(exp) # :nodoc: + # [[:lvar, :c], :var=, :"||", [:lit, 20]] + + _, lhs, index, msg, rhs = exp + + lhs = process lhs + index = index.to_s[0..-2] + rhs = process rhs + + "#{lhs}&.#{index} #{msg}= #{rhs}" + end + def process_sclass(exp) # :nodoc: - "class << #{process(exp.shift)}\n#{indent(process_block(exp))}\nend" + _, recv, *block = exp + + recv = process recv + block = indent process_block s(:block, *block) + + "class << #{recv}\n#{block}\nend" end def process_self(exp) # :nodoc: @@ -863,33 +958,41 @@ end def process_splat(exp) # :nodoc: - if exp.empty? then + _, arg = exp + if arg.nil? then "*" else - "*#{process(exp.shift)}" + "*#{process arg}" end end def process_str(exp) # :nodoc: - return exp.shift.dump + _, s = exp + s.dump end def process_super(exp) # :nodoc: - args = finish exp + _, *args = exp + + args = args.map { |arg| + process arg + } - "super(#{args.join(', ')})" + "super(#{args.join ", "})" end def process_svalue(exp) # :nodoc: - code = [] - until exp.empty? do - code << process(exp.shift) - end - code.join(", ") + _, *args = exp + + args.map { |arg| + process arg + }.join ", " end - def process_to_ary(exp) # :nodoc: - process(exp.shift) + def process_to_ary exp # :nodoc: + _, sexp = exp + + process sexp end def process_true(exp) # :nodoc: @@ -897,38 +1000,42 @@ end def process_undef(exp) # :nodoc: - "undef #{process(exp.shift)}" + _, name = exp + + "undef #{process name}" end def process_until(exp) # :nodoc: cond_loop(exp, 'until') end - def process_valias(exp) # :nodoc: - "alias #{exp.shift} #{exp.shift}" + def process_valias exp # :nodoc: + _, lhs, rhs = exp + + "alias #{lhs} #{rhs}" end - def process_when(exp) # :nodoc: - src = [] + def process_when exp # :nodoc: + s(:when, s(:array, s(:lit, 1)), + s(:call, nil, :puts, s(:str, "something")), + s(:lasgn, :result, s(:str, "red"))) - if self.context[1] == :array then # ugh. matz! why not an argscat?!? - val = process(exp.shift) - exp.shift # empty body - return "*#{val}" - end + _, lhs, *rhs = exp - until exp.empty? - cond = process(exp.shift).to_s[1..-2] - code = indent(finish(exp).join("\n")) - code = indent "# do nothing" if code =~ /\A\s*\Z/ - src << "when #{cond} then\n#{code.chomp}" - end + cond = process(lhs)[1..-2] - src.join("\n") + rhs = rhs.compact.map { |sexp| + indent process sexp + } + + rhs << indent("# do nothing") if rhs.empty? + rhs = rhs.join "\n" + + "when #{cond} then\n#{rhs.chomp}" end def process_while(exp) # :nodoc: - cond_loop(exp, 'while') + cond_loop exp, "while" end def process_xstr(exp) # :nodoc: @@ -936,10 +1043,11 @@ end def process_yield(exp) # :nodoc: - args = [] - until exp.empty? do - args << process(exp.shift) - end + _, *args = exp + + args = args.map { |arg| + process arg + } unless args.empty? then "yield(#{args.join(', ')})" @@ -957,21 +1065,42 @@ def rewrite_attrasgn exp # :nodoc: if context.first(2) == [:array, :masgn] then - exp[0] = :call - exp[2] = exp[2].to_s.sub(/=$/, '').to_sym + _, recv, msg, *args = exp + + exp = s(:call, recv, msg.to_s.chomp("=").to_sym, *args) end exp end + def rewrite_call exp # :nodoc: + _, recv, msg, *args = exp + + exp = s(:not, recv) if msg == :! && args.empty? + + exp + end + def rewrite_ensure exp # :nodoc: exp = s(:begin, exp) unless context.first == :begin exp end + def rewrite_if exp # :nodoc: + _, c, t, f = exp + + if c.sexp_type == :not then + _, nc = c + exp = s(:if, nc, f, t) + end + + exp + end + def rewrite_resbody exp # :nodoc: - raise "no exception list in #{exp.inspect}" unless exp.size > 2 && exp[1] - raise exp[1].inspect if exp[1][0] != :array + _, args, *_rest = exp + raise "no exception list in #{exp.inspect}" unless exp.size > 2 && args + raise args.inspect if args.sexp_type != :array # for now, do nothing, just check and freak if we see an errant structure exp end @@ -981,9 +1110,10 @@ complex ||= exp.size > 3 complex ||= exp.resbody.block complex ||= exp.resbody.size > 3 - complex ||= exp.find_nodes(:resbody).any? { |n| n[1] != s(:array) } - complex ||= exp.find_nodes(:resbody).any? { |n| n.last.nil? } - complex ||= exp.find_nodes(:resbody).any? { |n| n[2] and n[2].node_type == :block } + resbodies = exp.find_nodes(:resbody) + complex ||= resbodies.any? { |n| n[1] != s(:array) } + complex ||= resbodies.any? { |n| n.last.nil? } + complex ||= resbodies.any? { |(_, _, body)| body and body.node_type == :block } handled = context.first == :ensure @@ -993,9 +1123,9 @@ end def rewrite_svalue(exp) # :nodoc: - case exp.last.first + case exp.last.sexp_type when :array - s(:svalue, *exp[1][1..-1]) + s(:svalue, *exp[1].sexp_body) when :splat exp else @@ -1003,6 +1133,28 @@ end end + def rewrite_until exp # :nodoc: + _, c, *body = exp + + if c.sexp_type == :not then + _, nc = c + exp = s(:while, nc, *body) + end + + exp + end + + def rewrite_while exp # :nodoc: + _, c, *body = exp + + if c.sexp_type == :not then + _, nc = c + exp = s(:until, nc, *body) + end + + exp + end + ############################################################ # Utility Methods: @@ -1010,9 +1162,10 @@ # Generate a post-or-pre conditional loop. def cond_loop(exp, name) - cond = process(exp.shift) - body = process(exp.shift) - head_controlled = exp.shift + _, cond, body, head_controlled = exp + + cond = process cond + body = process body body = indent(body).chomp if body @@ -1026,6 +1179,7 @@ code << body if body code << "end #{name} #{cond}" end + code.join("\n") end @@ -1033,12 +1187,12 @@ # Utility method to escape something interpolated. def dthing_escape type, lit - lit = lit.gsub(/\n/, '\n') + # TODO: this needs more testing case type when :dregx then lit.gsub(/(\A|[^\\])\//, '\1\/') when :dstr, :dsym then - lit.gsub(/"/, '\"') + lit.dump[1..-2] when :dxstr then lit.gsub(/`/, '\`') else @@ -1047,21 +1201,9 @@ end ## - # Process all the remaining stuff in +exp+ and return the results - # sans-nils. - - def finish exp # REFACTOR: work this out of the rest of the processors - body = [] - until exp.empty? do - body << process(exp.shift) - end - body.compact - end - - ## # Indent all lines of +s+ to the current indent level. - def indent(s) + def indent s s.to_s.split(/\n/).map{|line| @indent + line}.join("\n") end @@ -1097,29 +1239,28 @@ # Utility method to generate something interpolated. def util_dthing(type, exp) - s = [] + _, str, *rest = exp # first item in sexp is a string literal - s << dthing_escape(type, exp.shift) + str = dthing_escape(type, str) - until exp.empty? - pt = exp.shift + rest = rest.map { |pt| case pt - when Sexp then - case pt.first + when Sexp then # TODO: what the fuck? why?? + case pt.sexp_type when :str then - s << dthing_escape(type, pt.last) + dthing_escape(type, pt.last) when :evstr then - s << '#{' << process(pt) << '}' # do not use interpolation here + '#{%s}' % [process(pt)] else raise "unknown type: #{pt.inspect}" end else raise "unhandled value in d-thing: #{pt.inspect}" end - end + } - s.join + [str, rest].join end ## @@ -1128,29 +1269,30 @@ def util_module_or_class(exp, is_class=false) result = [] - name = exp.shift + _, name, *body = exp + superk = body.shift if is_class + name = process name if Sexp === name result << name - if is_class then - superk = process(exp.shift) + if superk then + superk = process superk result << " < #{superk}" if superk end result << "\n" - body = [] - begin - code = process(exp.shift) unless exp.empty? - body << code.chomp unless code.nil? or code.chomp.empty? - end until exp.empty? + body = body.map { |sexp| + process(sexp).chomp + } unless body.empty? then body = indent(body.join("\n\n")) + "\n" else body = "" end + result << body result << "end" diff -Nru ruby-ruby2ruby-2.3.0/Manifest.txt ruby-ruby2ruby-2.4.1/Manifest.txt --- ruby-ruby2ruby-2.3.0/Manifest.txt 2016-03-30 23:22:41.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/Manifest.txt 2018-07-10 14:01:22.000000000 +0000 @@ -1,7 +1,7 @@ .autotest -History.txt +History.rdoc Manifest.txt -README.txt +README.rdoc Rakefile bin/r2r_show lib/ruby2ruby.rb Binary files /tmp/tmpC3L05N/hqQ40Xhor_/ruby-ruby2ruby-2.3.0/metadata.gz.sig and /tmp/tmpC3L05N/PAT_az3uYb/ruby-ruby2ruby-2.4.1/metadata.gz.sig differ diff -Nru ruby-ruby2ruby-2.3.0/Rakefile ruby-ruby2ruby-2.4.1/Rakefile --- ruby-ruby2ruby-2.3.0/Rakefile 2016-03-30 23:22:41.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/Rakefile 2018-07-10 14:01:22.000000000 +0000 @@ -9,13 +9,14 @@ Hoe.plugin :seattlerb Hoe.plugin :isolate +Hoe.plugin :rdoc Hoe.spec 'ruby2ruby' do developer 'Ryan Davis', 'ryand-ruby@zenspider.com' license "MIT" - dependency "sexp_processor", "~> 4.0" + dependency "sexp_processor", "~> 4.6" dependency "ruby_parser", "~> 3.1" end diff -Nru ruby-ruby2ruby-2.3.0/README.rdoc ruby-ruby2ruby-2.4.1/README.rdoc --- ruby-ruby2ruby-2.3.0/README.rdoc 1970-01-01 00:00:00.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/README.rdoc 2018-07-10 14:01:22.000000000 +0000 @@ -0,0 +1,87 @@ += ruby2ruby + +home :: https://github.com/seattlerb/ruby2ruby +rdoc :: http://docs.seattlerb.org/ruby2ruby + +== DESCRIPTION: + +ruby2ruby provides a means of generating pure ruby code easily from +RubyParser compatible Sexps. This makes making dynamic language +processors in ruby easier than ever! + +== FEATURES/PROBLEMS: + +* Clean, simple SexpProcessor generates ruby code from RubyParser compatible sexps. + +== SYNOPSIS: + + require 'rubygems' + require 'ruby2ruby' + require 'ruby_parser' + require 'pp' + + ruby = "def a\n puts 'A'\nend\n\ndef b\n a\nend" + parser = RubyParser.new + ruby2ruby = Ruby2Ruby.new + sexp = parser.process(ruby) + + pp sexp + + p ruby2ruby.process(sexp.deep_clone) # Note: #process destroys its input, so + # #deep_clone if you need to preserve it + + ## outputs: + + s(:block, + s(:defn, + :a, + s(:args), + s(:scope, s(:block, s(:call, nil, :puts, s(:arglist, s(:str, "A")))))), + s(:defn, :b, s(:args), s(:scope, s(:block, s(:call, nil, :a, s(:arglist)))))) + "def a\n puts(\"A\")\nend\ndef b\n a\nend\n" + +== REQUIREMENTS: + ++ sexp_processor ++ ruby_parser + +== INSTALL: + ++ sudo gem install ruby2ruby + +== How to Contribute: + +To get started all you need is a checkout, rake, and hoe. The easiest +way is: + + % git clone seattlerb/ruby2ruby # assumes you use the `hub` wrapper. + % gem i rake hoe + % rake install_plugins # installs hoe-seattlerb & isolate + % rake install_plugins # installs minitest (referenced from hoe-seattlerb) + +From here you should be good to go. We accept pull requests on github. + +== LICENSE: + +(The MIT License) + +Copyright (c) Ryan Davis, seattle.rb + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -Nru ruby-ruby2ruby-2.3.0/README.txt ruby-ruby2ruby-2.4.1/README.txt --- ruby-ruby2ruby-2.3.0/README.txt 2016-03-30 23:22:41.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/README.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -= ruby2ruby - -home :: https://github.com/seattlerb/ruby2ruby -rdoc :: http://docs.seattlerb.org/ruby2ruby - -== DESCRIPTION: - -ruby2ruby provides a means of generating pure ruby code easily from -RubyParser compatible Sexps. This makes making dynamic language -processors in ruby easier than ever! - -== FEATURES/PROBLEMS: - -* Clean, simple SexpProcessor generates ruby code from RubyParser compatible sexps. - -== SYNOPSIS: - - require 'rubygems' - require 'ruby2ruby' - require 'ruby_parser' - require 'pp' - - ruby = "def a\n puts 'A'\nend\n\ndef b\n a\nend" - parser = RubyParser.new - ruby2ruby = Ruby2Ruby.new - sexp = parser.process(ruby) - - pp sexp - - p ruby2ruby.process(sexp.deep_clone) # Note: #process destroys its input, so - # #deep_clone if you need to preserve it - - ## outputs: - - s(:block, - s(:defn, - :a, - s(:args), - s(:scope, s(:block, s(:call, nil, :puts, s(:arglist, s(:str, "A")))))), - s(:defn, :b, s(:args), s(:scope, s(:block, s(:call, nil, :a, s(:arglist)))))) - "def a\n puts(\"A\")\nend\ndef b\n a\nend\n" - -== REQUIREMENTS: - -+ sexp_processor -+ ruby_parser - -== INSTALL: - -+ sudo gem install ruby2ruby - -== How to Contribute: - -To get started all you need is a checkout, rake, and hoe. The easiest -way is: - - % git clone seattlerb/ruby2ruby # assumes you use the `hub` wrapper. - % gem i rake hoe - % rake install_plugins # installs hoe-seattlerb & isolate - % rake install_plugins # installs minitest (referenced from hoe-seattlerb) - -From here you should be good to go. We accept pull requests on github. - -== LICENSE: - -(The MIT License) - -Copyright (c) Ryan Davis, seattle.rb - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -Nru ruby-ruby2ruby-2.3.0/ruby2ruby.gemspec ruby-ruby2ruby-2.4.1/ruby2ruby.gemspec --- ruby-ruby2ruby-2.3.0/ruby2ruby.gemspec 2016-03-30 23:22:41.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/ruby2ruby.gemspec 2018-07-10 14:01:22.000000000 +0000 @@ -2,48 +2,46 @@ # This file has been automatically generated by gem2tgz # ######################################################### # -*- encoding: utf-8 -*- +# stub: ruby2ruby 2.4.1 ruby lib Gem::Specification.new do |s| - s.name = "ruby2ruby" - s.version = "2.3.0" + s.name = "ruby2ruby".freeze + s.version = "2.4.1" - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Ryan Davis"] - s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIDPjCCAiagAwIBAgIBAzANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu\nZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB\nGRYDY29tMB4XDTE1MDkxOTIwNTEyMloXDTE2MDkxODIwNTEyMlowRTETMBEGA1UE\nAwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS\nJomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda\nb9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx\ntaCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT\noOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh\nGiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt\nqhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV\ngBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB\nAQB+Hx8xUgrpZa4P8H8gR8zme5kISwQrG80MbpqJV6/G3/ZicRFhN5sjwu0uHGue\nbd9Cymf6oIRwHVarJux2M32T6bL07Hmi07w2QaPc3MnMKB/D46SRZ2JSSGPFRBTc\nSilobMRoGs/7B15uGFUEnNrCB/ltMqhwwSx1r++UQPfeySHEV9uqu03E5Vb7J37O\n2Er6PLXHRiYsIycD1LkMi6YnixdITRHmrqJYE2rsjaIfpIehiusVAPHkNf7qbpHq\nqx3h45R1CAsObX0SQDIT+rRbQrtKz1GHIZTOFYvEJjUY1XmRTZupD3CJ8Q7sDqSy\nNLq5jm1fq6Y9Uolu3RJbmycf\n-----END CERTIFICATE-----\n"] - s.date = "2016-02-19" - s.description = "ruby2ruby provides a means of generating pure ruby code easily from\nRubyParser compatible Sexps. This makes making dynamic language\nprocessors in ruby easier than ever!" - s.email = ["ryand-ruby@zenspider.com"] - s.executables = ["r2r_show"] - s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"] - s.files = [".autotest", "History.txt", "Manifest.txt", "README.txt", "Rakefile", "bin/r2r_show", "lib/ruby2ruby.rb", "test/test_ruby2ruby.rb"] - s.homepage = "https://github.com/seattlerb/ruby2ruby" - s.licenses = ["MIT"] - s.rdoc_options = ["--main", "README.txt"] - s.require_paths = ["lib"] - s.rubygems_version = "1.8.23" - s.summary = "ruby2ruby provides a means of generating pure ruby code easily from RubyParser compatible Sexps" + s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib".freeze] + s.authors = ["Ryan Davis".freeze] + s.cert_chain = ["-----BEGIN CERTIFICATE-----\nMIIDPjCCAiagAwIBAgIBAjANBgkqhkiG9w0BAQUFADBFMRMwEQYDVQQDDApyeWFu\nZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB\nGRYDY29tMB4XDTE3MTEyMTIxMTExMFoXDTE4MTEyMTIxMTExMFowRTETMBEGA1UE\nAwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS\nJomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda\nb9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx\ntaCPaLmfYIaFcHHCSY4hYDJijRQkLxPeB3xbOfzfLoBDbjvx5JxgJxUjmGa7xhcT\noOvjtt5P8+GSK9zLzxQP0gVLS/D0FmoE44XuDr3iQkVS2ujU5zZL84mMNqNB1znh\nGiadM9GHRaDiaxuX0cIUBj19T01mVE2iymf9I6bEsiayK/n6QujtyCbTWsAS9Rqt\nqhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV\ngBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw\nHQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBBQUAA4IB\nAQAfAXSQpsW7YSxd1csRtA/M4Zt0AMXFMd76GJ8Lgtg8G0+VFbdChRyDuDb0kPlW\nh9QQX/YABfCW8vxmssbMGrP+VGBAn7BbdTcfTlgCWrvMX1uL5aRL74nA4urKXqdW\na0nP70K4958P3GffBdtE3KGkU5xstFnXGajxuBRnL66E15KU0BNehVxdG258bdPu\nEKN6MqBPftFiev3tuwqDV11r2GquDpniYcT+Mi8/PgeAgVT/afBeVgbB3KaZeTRR\nAhXhF6Wi2GTMezlj5jlI5XV7WsJUSwTp/YiVvcmT74ZaCRvexm6EnNhkrvJJ1Xeu\nV+HB+LYYhXWitInO/eXxDrFB\n-----END CERTIFICATE-----\n".freeze] + s.date = "2018-02-15" + s.description = "ruby2ruby provides a means of generating pure ruby code easily from\nRubyParser compatible Sexps. This makes making dynamic language\nprocessors in ruby easier than ever!".freeze + s.email = ["ryand-ruby@zenspider.com".freeze] + s.executables = ["r2r_show".freeze] + s.extra_rdoc_files = ["History.rdoc".freeze, "Manifest.txt".freeze, "README.rdoc".freeze] + s.files = [".autotest".freeze, "History.rdoc".freeze, "Manifest.txt".freeze, "README.rdoc".freeze, "Rakefile".freeze, "bin/r2r_show".freeze, "lib/ruby2ruby.rb".freeze, "test/test_ruby2ruby.rb".freeze] + s.homepage = "https://github.com/seattlerb/ruby2ruby".freeze + s.licenses = ["MIT".freeze] + s.rdoc_options = ["--main".freeze, "README.rdoc".freeze] + s.rubygems_version = "2.5.2.1".freeze + s.summary = "ruby2ruby provides a means of generating pure ruby code easily from RubyParser compatible Sexps".freeze if s.respond_to? :specification_version then s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then - s.add_development_dependency(%q, ["~> 3.14"]) - s.add_development_dependency(%q, ["~> 5.8"]) - s.add_development_dependency(%q, ["~> 4.0"]) - s.add_runtime_dependency(%q, ["~> 3.1"]) - s.add_runtime_dependency(%q, ["~> 4.0"]) + s.add_development_dependency(%q.freeze, ["~> 3.16"]) + s.add_development_dependency(%q.freeze, ["~> 4.0"]) + s.add_runtime_dependency(%q.freeze, ["~> 3.1"]) + s.add_runtime_dependency(%q.freeze, ["~> 4.6"]) else - s.add_dependency(%q, ["~> 3.14"]) - s.add_dependency(%q, ["~> 5.8"]) - s.add_dependency(%q, ["~> 4.0"]) - s.add_dependency(%q, ["~> 3.1"]) - s.add_dependency(%q, ["~> 4.0"]) + s.add_dependency(%q.freeze, ["~> 3.16"]) + s.add_dependency(%q.freeze, ["~> 4.0"]) + s.add_dependency(%q.freeze, ["~> 3.1"]) + s.add_dependency(%q.freeze, ["~> 4.6"]) end else - s.add_dependency(%q, ["~> 3.14"]) - s.add_dependency(%q, ["~> 5.8"]) - s.add_dependency(%q, ["~> 4.0"]) - s.add_dependency(%q, ["~> 3.1"]) - s.add_dependency(%q, ["~> 4.0"]) + s.add_dependency(%q.freeze, ["~> 3.16"]) + s.add_dependency(%q.freeze, ["~> 4.0"]) + s.add_dependency(%q.freeze, ["~> 3.1"]) + s.add_dependency(%q.freeze, ["~> 4.6"]) end end diff -Nru ruby-ruby2ruby-2.3.0/test/test_ruby2ruby.rb ruby-ruby2ruby-2.4.1/test/test_ruby2ruby.rb --- ruby-ruby2ruby-2.3.0/test/test_ruby2ruby.rb 2016-03-30 23:22:41.000000000 +0000 +++ ruby-ruby2ruby-2.4.1/test/test_ruby2ruby.rb 2018-07-10 14:01:22.000000000 +0000 @@ -19,8 +19,6 @@ def self.generate_test klass, node, data, input_name, output_name output_name = data.has_key?('Ruby2Ruby') ? 'Ruby2Ruby' : 'Ruby' - return if node.to_s =~ /(str_question|not|bang).*_(19|20|21|22|23)$/ - klass.class_eval <<-EOM def test_#{node} pt = #{data[input_name].inspect} @@ -50,7 +48,6 @@ def test_util_dthing_dregx inn = util_thingy(:dregx) - inn.shift out = '/a"b#{(1 + 1)}c"d\/e/' exp = /a"b2c"d\/e/ @@ -61,7 +58,6 @@ def test_util_dthing_dstr inn = util_thingy(:dstr) - inn.shift out = '"a\"b#{(1 + 1)}c\"d/e"' exp = 'a"b2c"d/e' @@ -72,7 +68,6 @@ def test_util_dthing_dregx_bug? inn = s(:dregx, '[\/\"]', s(:evstr, s(:lit, 42))) - inn.shift out = '/[\/\"]#{42}/' exp = /[\/\"]42/ @@ -83,56 +78,56 @@ def test_hash_parens_str inn = s(:hash, s(:lit, :k), s(:str, "banana")) out = '{ :k => "banana" }' - util_compare inn, out + assert_parse inn, out end def test_hash_parens_lit inn = s(:hash, s(:lit, :k), s(:lit, 0.07)) out = "{ :k => 0.07 }" - util_compare inn, out + assert_parse inn, out end def test_hash_parens_bool inn = s(:hash, s(:lit, :k), s(:true)) out = "{ :k => true }" - util_compare inn, out + assert_parse inn, out end def test_hash_parens_nil inn = s(:hash, s(:lit, :k), s(:nil)) out = "{ :k => nil }" - util_compare inn, out + assert_parse inn, out end def test_hash_parens_lvar inn = s(:hash, s(:lit, :k), s(:lvar, :x)) out = "{ :k => x }" - util_compare inn, out + assert_parse inn, out end def test_hash_parens_call inn = s(:hash, s(:lit, :k), s(:call, nil, :foo, s(:lit, :bar))) out = "{ :k => foo(:bar) }" - util_compare inn, out + assert_parse inn, out end def test_hash_parens_iter iter = s(:iter, s(:call, nil, :foo), 0, s(:str, "bar")) inn = s(:hash, s(:lit, :k), iter) out = '{ :k => (foo { "bar" }) }' - util_compare inn, out + assert_parse inn, out end def test_and_alias inn = s(:and, s(:true), s(:alias, s(:lit, :a), s(:lit, :b))) out = "true and (alias :a :b)" - util_compare inn, out + assert_parse inn, out end def test_attr_reader_diff inn = s(:defn, :same, s(:args), s(:ivar, :@diff)) out = "def same\n @diff\nend" - util_compare inn, out + assert_parse inn, out end def test_attr_reader_same @@ -140,13 +135,13 @@ inn = s(:defn, :same, s(:args), s(:ivar, :@same)) out = "attr_reader :same" - util_compare inn, out + assert_parse inn, out end def test_attr_reader_double inn = s(:defn, :same, s(:args), s(:ivar, :@same), s(:ivar, :@diff)) out = "def same\n @same\n @diff\nend" - util_compare inn, out + assert_parse inn, out end def test_attr_reader_same_name_diff_body @@ -154,26 +149,126 @@ inn = s(:defn, :same, s(:args), s(:not, s(:ivar, :@same))) out = "def same\n (not @same)\nend" - util_compare inn, out + assert_parse inn, out end def test_attr_writer_diff inn = s(:defn, :same=, s(:args, :o), s(:iasgn, :@diff, s(:lvar, :o))) out = "def same=(o)\n @diff = o\nend" - util_compare inn, out + assert_parse inn, out + end + + def assert_str exp, src + assert_equal s(:str, exp), RubyParser.new.process(src) + end + + def assert_dstr exp, int, src + assert_equal s(:dstr, exp, s(:evstr, int).compact), RubyParser.new.process(src) + end + + def assert_r2r exp, sexp + assert_equal exp, Ruby2Ruby.new.process(sexp) + end + + def assert_rt src, exp=src.dup + assert_equal exp, Ruby2Ruby.new.process(RubyParser.new.parse(src)) + end + + def test_bug_033 + # gentle reminder to keep some sanity + # + # Use %q("...") for raw input strings + # Use %q(...) for raw output to avoid double-\'s + # Use %(...) for output strings + # + # don't use '...' at all + # only use "..." within sexps + + # "\t" + assert_str %(\t), %q("\t") + assert_r2r %q("\\t"), s(:str, "\t") + assert_rt %q("\t") + + # "\\t" + assert_str %(\t), %q("\\t") + assert_r2r %q("\\t"), s(:str, "\t") + assert_rt %q("\\t") + + # "\\\\t" + assert_str %(\\t), %q("\\\\t") + assert_r2r %q("\\\\t"), s(:str, "\\t") + assert_rt %q("\\\\t") + + # "\t#{}" + assert_dstr %(\t), nil, %q("\t#{}") + assert_r2r %q("\t#{}"), s(:dstr, "\t", s(:evstr)) + assert_rt %q("\t#{}") + + # "\\t#{}" + assert_dstr %(\t), nil, %q("\\t#{}") + assert_r2r %q("\\t#{}"), s(:dstr, "\t", s(:evstr)) + assert_rt %q("\\t#{}") + + # "\\\\t#{}" + assert_dstr %(\\t), nil, %q("\\\\t#{}") + assert_r2r %q("\\\\t#{}"), s(:dstr, "\\t", s(:evstr)) + assert_rt %q("\\\\t#{}") + end + + def test_bug_043 + inn = s(:defn, :check, s(:args), + s(:rescue, + s(:call, nil, :foo), + s(:resbody, s(:array), s(:call, nil, :bar), s(:call, nil, :bar))), + s(:call, nil, :bar), + s(:if, + s(:call, nil, :foo), + s(:return, s(:call, nil, :bar)), + s(:call, nil, :bar))) + + out = "def check\n begin\n foo\n rescue\n bar\n bar\n end\n bar\n if foo then\n return bar\n else\n bar\n end\nend" + + assert_parse inn, out + end + + def test_bug_044 + inn = s(:if, + s(:call, + s(:match3, s(:lit, /a/), s(:call, nil, :foo)), + :or, + s(:call, nil, :bar)), + s(:call, nil, :puts, s(:call, nil, :bar)), + nil) + out = "puts(bar) if (foo =~ /a/).or(bar)" + + assert_parse inn, out + end + + def test_bug_045 + # return foo.baaaaaaar ? ::B.newsss(true) : ::B.newadsfasdfasdfasdfasdsssss(false) + + inn = s(:return, + s(:if, + s(:call, s(:call, nil, :foo), :baaaaaaar), + s(:call, s(:colon3, :B), :newsss, s(:true)), + s(:call, s(:colon3, :B), :newadsfasdfasdfasdfasdsssss, s(:false)))) + + out = "return (if foo.baaaaaaar then\n ::B.newsss(true)\nelse\n ::B.newadsfasdfasdfasdfasdsssss(false)\nend)" + + assert_parse inn, out end def test_attr_writer_double inn = s(:defn, :same=, s(:args, :o), s(:iasgn, :@same, s(:lvar, :o)), s(:iasgn, :@diff, s(:lvar, :o))) out = "def same=(o)\n @same = o\n @diff = o\nend" - util_compare inn, out + assert_parse inn, out end def test_attr_writer_same_name_diff_body inn = s(:defn, :same=, s(:args, :o), s(:iasgn, :@same, s(:lit, 42))) out = "def same=(o)\n @same = 42\nend" - util_compare inn, out + assert_parse inn, out end def test_attr_writer_same @@ -181,7 +276,7 @@ inn = s(:defn, :same=, s(:args, :o), s(:iasgn, :@same , s(:lvar, :o))) out = "attr_writer :same" - util_compare inn, out + assert_parse inn, out end def test_dregx_slash @@ -189,32 +284,32 @@ inn = util_thingy(:dregx) out = '/a"b#{(1 + 1)}c"d\/e/' - util_compare inn, out, /a"b2c"d\/e/ + assert_parse inn, out, /a"b2c"d\/e/ end def test_dstr_quote inn = util_thingy(:dstr) out = '"a\"b#{(1 + 1)}c\"d/e"' - util_compare inn, out, 'a"b2c"d/e' + assert_parse inn, out, 'a"b2c"d/e' end def test_dsym_quote inn = util_thingy(:dsym) out = ':"a\"b#{(1 + 1)}c\"d/e"' - util_compare inn, out, :'a"b2c"d/e' + assert_parse inn, out, :'a"b2c"d/e' end def test_lit_regexp_slash do_not_check_sexp! # dunno why on this one - util_compare s(:lit, /blah\/blah/), '/blah\/blah/', /blah\/blah/ + assert_parse s(:lit, /blah\/blah/), '/blah\/blah/', /blah\/blah/ end def test_call_kwsplat inn = s(:call, nil, :test_splat, s(:hash, s(:kwsplat, s(:call, nil, :testing)))) out = "test_splat(**testing)" - util_compare inn, out + assert_parse inn, out end def test_call_arg_assoc_kwsplat @@ -223,14 +318,14 @@ s(:hash, s(:lit, :kw), s(:lit, 2), s(:kwsplat, s(:lit, 3)))) out = "f(1, :kw => 2, **3)" - util_compare inn, out + assert_parse inn, out end def test_call_kwsplat_x inn = s(:call, nil, :a, s(:hash, s(:kwsplat, s(:lit, 1)))) out = "a(**1)" - util_compare inn, out + assert_parse inn, out end def test_defn_kwargs @@ -239,7 +334,7 @@ s(:nil)) out = "def initialize(arg, keyword: nil, **args)\n # do nothing\nend" - util_compare inn, out + assert_parse inn, out end def test_defn_kwargs2 @@ -251,20 +346,20 @@ s(:nil)) out = "def initialize(arg, kw1: nil, kw2: nil, **args)\n # do nothing\nend" - util_compare inn, out + assert_parse inn, out end def test_call_self_index - util_compare s(:call, nil, :[], s(:lit, 42)), "self[42]" + assert_parse s(:call, nil, :[], s(:lit, 42)), "self[42]" end def test_call_self_index_equals - util_compare(s(:attrasgn, s(:self), :[]=, s(:lit, 42), s(:lit, 24)), + assert_parse(s(:attrasgn, s(:self), :[]=, s(:lit, 42), s(:lit, 24)), "self[42] = 24") end def test_call_self_index_equals_array - util_compare(s(:attrasgn, s(:self), :[]=, s(:lit, 1), s(:lit, 2), s(:lit, 3)), + assert_parse(s(:attrasgn, s(:self), :[]=, s(:lit, 1), s(:lit, 2), s(:lit, 3)), "self[1, 2] = 3") end @@ -274,7 +369,7 @@ s(:call, nil, :b)) out = "method({ :a => 1 }, b)" - util_compare inn, out + assert_parse inn, out end def test_call_arglist_hash_first_last @@ -284,7 +379,7 @@ s(:hash, s(:lit, :c), s(:lit, 1))) out = "method({ :a => 1 }, b, :c => 1)" - util_compare inn, out + assert_parse inn, out end def test_call_arglist_hash_last @@ -293,7 +388,7 @@ s(:hash, s(:lit, :a), s(:lit, 1))) out = "method(b, :a => 1)" - util_compare inn, out + assert_parse inn, out end def test_call_arglist_if @@ -306,7 +401,7 @@ s(:call, nil, :d))) out = "(a + (b ? (c) : (d)))" - util_compare inn, out + assert_parse inn, out end def test_defn_kwsplat @@ -337,7 +432,7 @@ s(:evstr, s(:lvar, :b)))) out = 'nil.x { |(a, b)| "#{a}=#{b}" }' - util_compare inn, out + assert_parse inn, out end def test_masgn_wtf @@ -357,7 +452,7 @@ out = "k, v = *line.split(/\\=/, 2)\nself[k] = v.strip\n" - util_compare inn, out + assert_parse inn, out end def test_masgn_splat_wtf @@ -369,14 +464,14 @@ :split, s(:lit, /\=/), s(:lit, 2)))) out = 'k, v = *line.split(/\\=/, 2)' - util_compare inn, out + assert_parse inn, out end def test_match3_asgn inn = s(:match3, s(:lit, //), s(:lasgn, :y, s(:call, nil, :x))) out = "(y = x) =~ //" # "y = x =~ //", which matches on x and assigns to y (not what sexp says). - util_compare inn, out + assert_parse inn, out end def test_safe_attrasgn @@ -387,7 +482,7 @@ out = "x&.y = 1" - util_compare inn, out + assert_parse inn, out end def test_safe_call @@ -399,7 +494,7 @@ s(:lit, 1)) out ="x&.y&.z(1)" - util_compare inn, out + assert_parse inn, out end def test_safe_call_binary @@ -409,7 +504,29 @@ s(:lit, 1)) out = "x&.>(1)" - util_compare inn, out + assert_parse inn, out + end + + def test_safe_op_asgn + inn = s(:safe_op_asgn, + s(:call, nil, :x), + s(:call, nil, :z, s(:lit, 1)), + :y, + :+) + + out = "x&.y += z(1)" + assert_parse inn, out + end + + def test_safe_op_asgn2 + inn = s(:safe_op_asgn2, + s(:call, nil, :x), + :y=, + :"||", + s(:lit, 1)) + + out = "x&.y ||= 1" + assert_parse inn, out end def test_splat_call @@ -421,7 +538,7 @@ s(:lit, /\=/), s(:lit, 2)))) out = 'x(*line.split(/\=/, 2))' - util_compare inn, out + assert_parse inn, out end def test_resbody_block @@ -433,7 +550,7 @@ s(:call, nil, :x3))) out = "begin\n x1\nrescue\n x2\n x3\nend" - util_compare inn, out + assert_parse inn, out end def test_resbody_short_with_begin_end @@ -442,7 +559,7 @@ s(:call, nil, :blah), s(:resbody, s(:array), s(:array))) out = "blah rescue []" - util_compare inn, out + assert_parse inn, out end def test_resbody_short_with_begin_end_multiple @@ -453,7 +570,7 @@ s(:call, nil, :log), s(:call, nil, :raise))) out = "begin\n blah\nrescue\n log\n raise\nend" - util_compare inn, out + assert_parse inn, out end def test_resbody_short_with_defn_multiple @@ -467,7 +584,7 @@ s(:call, nil, :log), s(:call, nil, :raise)))) out = "def foo\n a = 1\nrescue\n log\n raise\nend" - util_compare inn, out + assert_parse inn, out end def test_regexp_options @@ -479,7 +596,7 @@ 4), s(:str, "a")) out = '"a" =~ /abc#{x}def/m' - util_compare inn, out + assert_parse inn, out end def test_resbody_short_with_rescue_args @@ -487,7 +604,7 @@ s(:call, nil, :blah), s(:resbody, s(:array, s(:const, :A), s(:const, :B)), s(:array))) out = "begin\n blah\nrescue A, B\n []\nend" - util_compare inn, out + assert_parse inn, out end def test_call_binary_call_with_hash_arg @@ -503,7 +620,7 @@ out = "(args << { :key => 24 }) if 42" - util_compare inn, out + assert_parse inn, out end def test_binary_operators @@ -511,20 +628,28 @@ Ruby2Ruby::BINARY.each do |op| inn = s(:call, s(:lit, 1), op, s(:lit, 2)) out = "(1 #{op} 2)" - util_compare inn, out + assert_parse inn, out + end + end + + def test_binary_operators_with_multiple_arguments + Ruby2Ruby::BINARY.each do |op| + inn = s(:call, s(:lvar, :x), op, s(:lit, 2), s(:lit, 3)) + out = "x.#{op}(2, 3)" + assert_parse inn, out end end def test_call_empty_hash inn = s(:call, nil, :foo, s(:hash)) out = "foo({})" - util_compare inn, out + assert_parse inn, out end def test_if_empty inn = s(:if, s(:call, nil, :x), nil, nil) out = "if x then\n # do nothing\nend" - util_compare inn, out + assert_parse inn, out end def test_interpolation_and_escapes @@ -535,60 +660,71 @@ s(:str, "m"), s(:evstr, s(:call, nil, :message)), s(:str, "\e[0m "))) - out = "log_entry = \" \e[#\{message_color}m#\{message}\e[0m \"" + out = "log_entry = \" \\e[#\{message_color}m#\{message}\\e[0m \"" - util_compare inn, out + assert_parse inn, out end def test_class_comments inn = s(:class, :Z, nil) inn.comments = "# x\n# y\n" out = "# x\n# y\nclass Z\nend" - util_compare inn, out + assert_parse inn, out end def test_module_comments inn = s(:module, :Z) inn.comments = "# x\n# y\n" out = "# x\n# y\nmodule Z\nend" - util_compare inn, out + assert_parse inn, out end def test_method_comments inn = s(:defn, :z, s(:args), s(:nil)) inn.comments = "# x\n# y\n" out = "# x\n# y\ndef z\n # do nothing\nend" - util_compare inn, out + assert_parse inn, out end def test_basic_ensure inn = s(:ensure, s(:lit, 1), s(:lit, 2)) out = "begin\n 1\nensure\n 2\nend" - util_compare inn, out + assert_parse inn, out end def test_nested_ensure inn = s(:ensure, s(:lit, 1), s(:ensure, s(:lit, 2), s(:lit, 3))) out = "begin\n 1\nensure\n begin\n 2\n ensure\n 3\n end\nend" - util_compare inn, out + assert_parse inn, out end def test_nested_rescue inn = s(:ensure, s(:lit, 1), s(:rescue, s(:lit, 2), s(:resbody, s(:array), s(:lit, 3)))) out = "begin\n 1\nensure\n 2 rescue 3\nend" - util_compare inn, out + assert_parse inn, out end def test_nested_rescue_exception inn = s(:ensure, s(:lit, 1), s(:rescue, s(:lit, 2), s(:resbody, s(:array, s(:const, :Exception)), s(:lit, 3)))) out = "begin\n 1\nensure\n begin\n 2\n rescue Exception\n 3\n end\nend" - util_compare inn, out + assert_parse inn, out end def test_nested_rescue_exception2 inn = s(:ensure, s(:rescue, s(:lit, 2), s(:resbody, s(:array, s(:const, :Exception)), s(:lit, 3))), s(:lit, 1)) out = "begin\n 2\nrescue Exception\n 3\nensure\n 1\nend" - util_compare inn, out + assert_parse inn, out + end + + def test_op_asgn + inn = s(:op_asgn, + s(:call, nil, :x), + s(:call, nil, :z, s(:lit, 1)), + :y, + :+) + + out = "x.y += z(1)" + assert_parse inn, out end def test_rescue_block @@ -598,7 +734,7 @@ s(:call, nil, :beta), s(:call, nil, :gamma))) out = "begin\n alpha\nrescue\n beta\n gamma\nend" - util_compare inn, out + assert_parse inn, out end def test_array_adds_parens_around_rescue @@ -607,7 +743,7 @@ s(:rescue, s(:call, nil, :b), s(:resbody, s(:array), s(:call, nil, :c)))) out = "[a, (b rescue c)]" - util_compare inn, out + assert_parse inn, out end def test_call_arglist_rescue @@ -618,7 +754,7 @@ s(:call, nil, :a), s(:resbody, s(:array), s(:call, nil, :b)))) out = "method((a rescue b))" - util_compare inn, out + assert_parse inn, out end def test_unless_vs_if_not @@ -626,14 +762,17 @@ rb2 = "a if (not b)" rb3 = "a if ! b" - util_compare Ruby18Parser.new.parse(rb1), rb1 - util_compare Ruby19Parser.new.parse(rb1), rb1 - - util_compare Ruby18Parser.new.parse(rb2), rb1 - util_compare Ruby19Parser.new.parse(rb2), rb2 - - util_compare Ruby18Parser.new.parse(rb3), rb1 - util_compare Ruby19Parser.new.parse(rb3), rb2 + assert_parse Ruby18Parser.new.parse(rb1), rb1 + assert_parse Ruby19Parser.new.parse(rb1), rb1 + assert_parse Ruby25Parser.new.parse(rb1), rb1 + + assert_parse Ruby18Parser.new.parse(rb2), rb1 + assert_parse Ruby19Parser.new.parse(rb2), rb1 + assert_parse Ruby25Parser.new.parse(rb2), rb1 + + assert_parse Ruby18Parser.new.parse(rb3), rb1 + assert_parse Ruby19Parser.new.parse(rb3), rb1 + assert_parse Ruby25Parser.new.parse(rb3), rb1 end def assert_parse sexp, expected_ruby, expected_eval = nil @@ -643,7 +782,6 @@ assert_equal expected_ruby, @processor.process(sexp), "sexp -> ruby" assert_equal expected_eval, eval(expected_ruby) if expected_eval end - alias util_compare assert_parse def util_thingy(type) s(type,