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

ruby-changes:48093

From: nobu <ko1@a...>
Date: Wed, 18 Oct 2017 22:08:59 +0900 (JST)
Subject: [ruby-changes:48093] nobu:r60207 (trunk): parse.y: serial comparisons

nobu	2017-10-18 22:08:53 +0900 (Wed, 18 Oct 2017)

  New Revision: 60207

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

  Log:
    parse.y: serial comparisons
    
    * parse.y (rel_expr): warn sequence of comparisons, which would be
      probably unintentional.  [EXPERIMENTAL]

  Modified files:
    trunk/parse.y
    trunk/test/ruby/test_parse.rb
Index: parse.y
===================================================================
--- parse.y	(revision 60206)
+++ parse.y	(revision 60207)
@@ -773,6 +773,7 @@ static ID id_warn, id_warning, id_gets; https://github.com/ruby/ruby/blob/trunk/parse.y#L773
 # define WARN_S_L(s,l) STR_NEW(s,l)
 # define WARN_S(s) STR_NEW2(s)
 # define WARN_I(i) INT2NUM(i)
+# define WARN_ID(i) rb_id2str(i)
 # define PRIsWARN "s"
 # define WARN_ARGS(fmt,n) parser->value, id_warn, n, rb_usascii_str_new_lit(fmt)
 # define WARN_ARGS_L(l,fmt,n) WARN_ARGS(fmt,n)
@@ -795,6 +796,7 @@ PRINTF_ARGS(static void ripper_compile_e https://github.com/ruby/ruby/blob/trunk/parse.y#L796
 # define WARN_S_L(s,l) s
 # define WARN_S(s) s
 # define WARN_I(i) i
+# define WARN_ID(i) rb_id2name(i)
 # define PRIsWARN PRIsVALUE
 # define WARN_ARGS(fmt,n) WARN_ARGS_L(ruby_sourceline,fmt,n)
 # define WARN_ARGS_L(l,fmt,n) ruby_sourcefile, (l), (fmt)
@@ -896,7 +898,7 @@ static void token_info_pop_gen(struct pa https://github.com/ruby/ruby/blob/trunk/parse.y#L898
 %type <node> literal numeric simple_numeric dsym cpath
 %type <node> top_compstmt top_stmts top_stmt
 %type <node> bodystmt compstmt stmts stmt_or_begin stmt expr arg primary command command_call method_call
-%type <node> expr_value arg_value primary_value fcall
+%type <node> expr_value arg_value primary_value fcall rel_expr
 %type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
 %type <node> args call_args opt_call_args
 %type <node> paren_args opt_paren_args args_tail opt_args_tail block_args_tail opt_block_args_tail
@@ -2093,10 +2095,7 @@ arg		: lhs '=' arg_rhs https://github.com/ruby/ruby/blob/trunk/parse.y#L2095
 		    {
 			$$ = call_bin_op($1, idCmp, $3);
 		    }
-		| arg relop arg   %prec '>'
-		    {
-			$$ = call_bin_op($1, $2, $3);
-		    }
+		| rel_expr   %prec tCMP
 		| arg tEQ arg
 		    {
 			$$ = call_bin_op($1, idEq, $3);
@@ -2172,6 +2171,17 @@ relop		: '>'  {$$ = '>';} https://github.com/ruby/ruby/blob/trunk/parse.y#L2171
 		| tLEQ {$$ = idLE;}
 		;
 
+rel_expr	: arg relop arg   %prec '>'
+		    {
+			$$ = call_bin_op($1, $2, $3);
+		    }
+		| rel_expr relop arg   %prec '>'
+		    {
+			rb_warning1("comparison '%s' after comparison", WARN_ID($2));
+			$$ = call_bin_op($1, $2, $3);
+		    }
+		;
+
 arg_value	: arg
 		    {
 		    /*%%%*/
Index: test/ruby/test_parse.rb
===================================================================
--- test/ruby/test_parse.rb	(revision 60206)
+++ test/ruby/test_parse.rb	(revision 60207)
@@ -1069,6 +1069,14 @@ x = __ENCODING__ https://github.com/ruby/ruby/blob/trunk/test/ruby/test_parse.rb#L1069
     assert_equal(1.3, o.x)
   end
 
+  def test_serial_comparison
+    assert_warning(/comparison '<' after/) do
+      $VERBOSE = true
+      x = 1
+      eval("if false; 0 < x < 2; end")
+    end
+  end
+
 =begin
   def test_past_scope_variable
     assert_warning(/past scope/) {catch {|tag| eval("BEGIN{throw tag}; tap {a = 1}; a")}}

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

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