[前][次][番号順一覧][スレッド一覧]

ruby-changes:36063

From: nobu <ko1@a...>
Date: Sun, 26 Oct 2014 12:24:27 +0900 (JST)
Subject: [ruby-changes:36063] nobu:r48144 (trunk): parse.y: Ripper.sexp returns error

nobu	2014-10-26 12:24:18 +0900 (Sun, 26 Oct 2014)

  New Revision: 48144

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=48144

  Log:
    parse.y: Ripper.sexp returns error
    
    * ext/ripper/lib/ripper/sexp.rb (Ripper.sexp, Ripper.sexp_raw):
      return nil on error.  [ruby-dev:48678] [Bug #10405]

  Added files:
    trunk/test/ripper/test_sexp.rb
  Modified files:
    trunk/ChangeLog
    trunk/ext/ripper/lib/ripper/sexp.rb
    trunk/parse.y
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 48143)
+++ ChangeLog	(revision 48144)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Oct 26 12:24:15 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* ext/ripper/lib/ripper/sexp.rb (Ripper.sexp, Ripper.sexp_raw):
+	  return nil on error.  [ruby-dev:48678] [Bug #10405]
+
 Sun Oct 25 11:24:24 2014  Martin Duerst <duerst@i...>
 
 	* string.c: improved comment.
Index: parse.y
===================================================================
--- parse.y	(revision 48143)
+++ parse.y	(revision 48144)
@@ -278,6 +278,7 @@ struct parser_params { https://github.com/ruby/ruby/blob/trunk/parse.y#L278
     VALUE result;
     VALUE parsing_thread;
     int toplevel_p;
+    int error_p;
 #endif
 };
 
@@ -549,6 +550,8 @@ static VALUE ripper_dispatch3(struct par https://github.com/ruby/ruby/blob/trunk/parse.y#L550
 static VALUE ripper_dispatch4(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE);
 static VALUE ripper_dispatch5(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE);
 static VALUE ripper_dispatch7(struct parser_params*,ID,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE,VALUE);
+static void ripper_error_gen(struct parser_params *parser);
+#define ripper_error() ripper_error_gen(parser)
 
 #define dispatch0(n)            ripper_dispatch0(parser, TOKEN_PASTE(ripper_id_, n))
 #define dispatch1(n,a)          ripper_dispatch1(parser, TOKEN_PASTE(ripper_id_, n), (a))
@@ -1086,6 +1089,7 @@ stmt		: keyword_alias fitem {lex_state = https://github.com/ruby/ruby/blob/trunk/parse.y#L1089
 		    /*%
 			$$ = dispatch2(var_alias, $2, $3);
 			$$ = dispatch1(alias_error, $$);
+			ripper_error();
 		    %*/
 		    }
 		| keyword_undef undef_list
@@ -1231,6 +1235,7 @@ stmt		: keyword_alias fitem {lex_state = https://github.com/ruby/ruby/blob/trunk/parse.y#L1235
 		    /*%
 			$$ = dispatch2(assign, dispatch1(var_field, $1), $3);
 			$$ = dispatch1(assign_error, $$);
+			ripper_error();
 		    %*/
 		    }
 		| lhs '=' mrhs
@@ -1684,6 +1689,7 @@ mlhs_node	: user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1689
 			$$ = dispatch2(const_path_field, $1, $3);
 			if (in_def || in_single) {
 			    $$ = dispatch1(assign_error, $$);
+			    ripper_error();
 			}
 		    %*/
 		    }
@@ -1697,6 +1703,7 @@ mlhs_node	: user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1703
 			$$ = dispatch1(top_const_field, $2);
 			if (in_def || in_single) {
 			    $$ = dispatch1(assign_error, $$);
+			    ripper_error();
 			}
 		    %*/
 		    }
@@ -1708,6 +1715,7 @@ mlhs_node	: user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1715
 		    /*%
 			$$ = dispatch1(var_field, $1);
 			$$ = dispatch1(assign_error, $$);
+			ripper_error();
 		    %*/
 		    }
 		;
@@ -1772,6 +1780,7 @@ lhs		: user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1780
 			$$ = dispatch2(const_path_field, $1, $3);
 			if (in_def || in_single) {
 			    $$ = dispatch1(assign_error, $$);
+			    ripper_error();
 			}
 		    %*/
 		    }
@@ -1785,6 +1794,7 @@ lhs		: user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1794
 			$$ = dispatch1(top_const_field, $2);
 			if (in_def || in_single) {
 			    $$ = dispatch1(assign_error, $$);
+			    ripper_error();
 			}
 		    %*/
 		    }
@@ -1795,6 +1805,7 @@ lhs		: user_variable https://github.com/ruby/ruby/blob/trunk/parse.y#L1805
 			$$ = NEW_BEGIN(0);
 		    /*%
 			$$ = dispatch1(assign_error, $1);
+			ripper_error();
 		    %*/
 		    }
 		;
@@ -1805,6 +1816,7 @@ cname		: tIDENTIFIER https://github.com/ruby/ruby/blob/trunk/parse.y#L1816
 			yyerror("class/module name must be CONSTANT");
 		    /*%
 			$$ = dispatch1(class_name_error, $1);
+			ripper_error();
 		    %*/
 		    }
 		| tCONSTANT
@@ -2038,6 +2050,7 @@ arg		: lhs '=' arg https://github.com/ruby/ruby/blob/trunk/parse.y#L2050
 			$$ = dispatch1(var_field, $1);
 			$$ = dispatch3(opassign, $$, $2, $3);
 			$$ = dispatch1(assign_error, $$);
+			ripper_error();
 		    %*/
 		    }
 		| arg tDOT2 arg
@@ -4536,6 +4549,7 @@ f_bad_arg	: tCONSTANT https://github.com/ruby/ruby/blob/trunk/parse.y#L4549
 			$$ = 0;
 		    /*%
 			$$ = dispatch1(param_error, $1);
+			ripper_error();
 		    %*/
 		    }
 		| tIVAR
@@ -4545,6 +4559,7 @@ f_bad_arg	: tCONSTANT https://github.com/ruby/ruby/blob/trunk/parse.y#L4559
 			$$ = 0;
 		    /*%
 			$$ = dispatch1(param_error, $1);
+			ripper_error();
 		    %*/
 		    }
 		| tGVAR
@@ -4554,6 +4569,7 @@ f_bad_arg	: tCONSTANT https://github.com/ruby/ruby/blob/trunk/parse.y#L4569
 			$$ = 0;
 		    /*%
 			$$ = dispatch1(param_error, $1);
+			ripper_error();
 		    %*/
 		    }
 		| tCVAR
@@ -4563,6 +4579,7 @@ f_bad_arg	: tCONSTANT https://github.com/ruby/ruby/blob/trunk/parse.y#L4579
 			$$ = 0;
 		    /*%
 			$$ = dispatch1(param_error, $1);
+			ripper_error();
 		    %*/
 		    }
 		;
@@ -5315,6 +5332,7 @@ parser_yyerror(struct parser_params *par https://github.com/ruby/ruby/blob/trunk/parse.y#L5332
     }
 #else
     dispatch1(parse_error, STR_NEW2(msg));
+    ripper_error();
 #endif /* !RIPPER */
     return 0;
 }
@@ -8759,7 +8777,7 @@ assignable_gen(struct parser_params *par https://github.com/ruby/ruby/blob/trunk/parse.y#L8777
 #ifdef RIPPER
     ID id = get_id(lhs);
 # define assignable_result(x) get_value(lhs)
-# define parser_yyerror(parser, x) dispatch1(assign_error, lhs)
+# define parser_yyerror(parser, x) (dispatch1(assign_error, lhs), ripper_error())
 #else
 # define assignable_result(x) (x)
 #endif
@@ -10247,6 +10265,7 @@ parser_initialize(struct parser_params * https://github.com/ruby/ruby/blob/trunk/parse.y#L10265
     parser->result = Qnil;
     parser->parsing_thread = Qnil;
     parser->toplevel_p = TRUE;
+    parser->error_p = FALSE;
 #endif
 #ifdef YYMALLOC
     parser->heap = NULL;
@@ -10369,6 +10388,21 @@ static VALUE ripper_parser_end_seen_p(VA https://github.com/ruby/ruby/blob/trunk/parse.y#L10388
 static VALUE ripper_parser_encoding(VALUE vparser);
 static VALUE ripper_parser_get_yydebug(VALUE self);
 static VALUE ripper_parser_set_yydebug(VALUE self, VALUE flag);
+
+/*
+ *  call-seq:
+ *    ripper#error?   -> Boolean
+ *
+ *  Return true if parsed source has errors.
+ */
+static VALUE
+ripper_error_p(VALUE vparser)
+{
+    struct parser_params *parser;
+
+    TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, parser);
+    return parser->error_p ? Qtrue : Qfalse;
+}
 #endif
 
 /*
@@ -10722,6 +10756,12 @@ ripper_get_value(VALUE v) https://github.com/ruby/ruby/blob/trunk/parse.y#L10756
 }
 
 static void
+ripper_error_gen(struct parser_params *parser)
+{
+    parser->error_p = TRUE;
+}
+
+static void
 ripper_compile_error(struct parser_params *parser, const char *fmt, ...)
 {
     VALUE str;
@@ -10731,6 +10771,7 @@ ripper_compile_error(struct parser_param https://github.com/ruby/ruby/blob/trunk/parse.y#L10771
     str = rb_vsprintf(fmt, args);
     va_end(args);
     rb_funcall(parser->value, rb_intern("compile_error"), 1, str);
+    ripper_error_gen(parser);
 }
 
 static void
@@ -11011,6 +11052,7 @@ InitVM_ripper(void) https://github.com/ruby/ruby/blob/trunk/parse.y#L11052
     rb_define_method(Ripper, "encoding", rb_parser_encoding, 0);
     rb_define_method(Ripper, "yydebug", rb_parser_get_yydebug, 0);
     rb_define_method(Ripper, "yydebug=", rb_parser_set_yydebug, 1);
+    rb_define_method(Ripper, "error?", ripper_error_p, 0);
 #ifdef RIPPER_DEBUG
     rb_define_method(rb_mKernel, "assert_Qundef", ripper_assert_Qundef, 2);
     rb_define_method(rb_mKernel, "rawVALUE", ripper_value, 1);
Index: ext/ripper/lib/ripper/sexp.rb
===================================================================
--- ext/ripper/lib/ripper/sexp.rb	(revision 48143)
+++ ext/ripper/lib/ripper/sexp.rb	(revision 48144)
@@ -28,7 +28,9 @@ class Ripper https://github.com/ruby/ruby/blob/trunk/ext/ripper/lib/ripper/sexp.rb#L28
   #           [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]]
   #
   def Ripper.sexp(src, filename = '-', lineno = 1)
-    SexpBuilderPP.new(src, filename, lineno).parse
+    builder = SexpBuilderPP.new(src, filename, lineno)
+    sexp = builder.parse
+    sexp unless builder.error?
   end
 
   # [EXPERIMENTAL]
@@ -52,7 +54,9 @@ class Ripper https://github.com/ruby/ruby/blob/trunk/ext/ripper/lib/ripper/sexp.rb#L54
   #             nil]]]]
   #
   def Ripper.sexp_raw(src, filename = '-', lineno = 1)
-    SexpBuilder.new(src, filename, lineno).parse
+    builder = SexpBuilder.new(src, filename, lineno)
+    sexp = builder.parse
+    sexp unless builder.error?
   end
 
   class SexpBuilderPP < ::Ripper   #:nodoc:
Index: test/ripper/test_sexp.rb
===================================================================
--- test/ripper/test_sexp.rb	(revision 0)
+++ test/ripper/test_sexp.rb	(revision 48144)
@@ -0,0 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/test/ripper/test_sexp.rb#L1
+begin
+  require 'ripper'
+  require 'test/unit'
+  ripper_test = true
+  module TestRipper; end
+rescue LoadError
+end
+
+class TestRipper::Sexp < Test::Unit::TestCase
+  def test_compile_error
+    assert_nil Ripper.sexp("/")
+    assert_nil Ripper.sexp("-")
+    assert_nil Ripper.sexp("+")
+    assert_nil Ripper.sexp("*")
+    assert_nil Ripper.sexp("end")
+    assert_nil Ripper.sexp("end 1")
+  end
+end if ripper_test

Property changes on: test/ripper/test_sexp.rb
___________________________________________________________________
Added: svn:eol-style
   + LF


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]