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

ruby-changes:48247

From: yui-knk <ko1@a...>
Date: Sun, 22 Oct 2017 22:18:46 +0900 (JST)
Subject: [ruby-changes:48247] yui-knk:r60362 (trunk): Add column numbers to branch coverage

yui-knk	2017-10-22 22:18:40 +0900 (Sun, 22 Oct 2017)

  New Revision: 60362

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

  Log:
    Add column numbers to branch coverage
    
    * compile.c (DECL_BRANCH_BASE, ADD_TRACE_BRANCH_COVERAGE): Add
      column to arguments.
    
    * compile.c (compile_if, compile_case, compile_when, compile_loop, iseq_compile_each0):
      Pass column numbers to macros.
    
    * ext/coverage/coverage.c (branch_coverage): Add column numbers to
      a return value.
    
    * test/coverage/test_coverage.rb: Follow-up these changes.

  Modified files:
    trunk/compile.c
    trunk/ext/coverage/coverage.c
    trunk/test/coverage/test_coverage.rb
Index: ext/coverage/coverage.c
===================================================================
--- ext/coverage/coverage.c	(revision 60361)
+++ ext/coverage/coverage.c	(revision 60362)
@@ -82,13 +82,15 @@ branch_coverage(VALUE branches) https://github.com/ruby/ruby/blob/trunk/ext/coverage/coverage.c#L82
 	VALUE branches = RARRAY_AREF(structure, i);
 	VALUE base_type = RARRAY_AREF(branches, 0);
 	VALUE base_lineno = RARRAY_AREF(branches, 1);
+	VALUE base_column = RARRAY_AREF(branches, 2);
 	VALUE children = rb_hash_new();
-	rb_hash_aset(ret, rb_ary_new_from_args(3, base_type, LONG2FIX(id++), base_lineno), children);
-	for (j = 2; j < RARRAY_LEN(branches); j += 3) {
+	rb_hash_aset(ret, rb_ary_new_from_args(4, base_type, LONG2FIX(id++), base_lineno, base_column), children);
+	for (j = 3; j < RARRAY_LEN(branches); j += 4) {
 	    VALUE target_label = RARRAY_AREF(branches, j);
 	    VALUE target_lineno = RARRAY_AREF(branches, j + 1);
-	    int idx = FIX2INT(RARRAY_AREF(branches, j + 2));
-	    rb_hash_aset(children, rb_ary_new_from_args(3, target_label, LONG2FIX(id++), target_lineno), RARRAY_AREF(counters, idx));
+	    VALUE target_column = RARRAY_AREF(branches, j + 2);
+	    int idx = FIX2INT(RARRAY_AREF(branches, j + 3));
+	    rb_hash_aset(children, rb_ary_new_from_args(4, target_label, LONG2FIX(id++), target_lineno, target_column), RARRAY_AREF(counters, idx));
 	}
     }
 
Index: test/coverage/test_coverage.rb
===================================================================
--- test/coverage/test_coverage.rb	(revision 60361)
+++ test/coverage/test_coverage.rb	(revision 60362)
@@ -197,8 +197,8 @@ class TestCoverage < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/coverage/test_coverage.rb#L197
   def test_branch_coverage_for_if_statement
     result = {
       :branches => {
-        [:if    , 0, 2] => {[:then, 1,  3]=>2, [:else, 2, 5]=>1},
-        [:unless, 3, 8] => {[:else, 4, 11]=>2, [:then, 5, 9]=>1},
+        [:if    , 0, 2, 8] => {[:then, 1,  3, 10]=>2, [:else, 2, 5, 10]=>1},
+        [:unless, 3, 8, 8] => {[:else, 4, 11, 10]=>2, [:then, 5, 9, 10]=>1},
       }
     }
     assert_coverage(<<-"end;", { branches: true }, result)
@@ -225,8 +225,8 @@ class TestCoverage < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/coverage/test_coverage.rb#L225
   def test_branch_coverage_for_while_statement
     result = {
       :branches => {
-        [:while, 0, 2] => {[:body, 1, 3]=> 3},
-        [:until, 2, 5] => {[:body, 3, 6]=>10},
+        [:while, 0, 2, 6] => {[:body, 1, 3, 8]=> 3},
+        [:until, 2, 5, 6] => {[:body, 3, 6, 8]=>10},
       }
     }
     assert_coverage(<<-"end;", { branches: true }, result)
@@ -243,10 +243,10 @@ class TestCoverage < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/coverage/test_coverage.rb#L243
   def test_branch_coverage_for_case_statement
     result = {
       :branches => {
-        [:case,  0,  2] => {[:when,  1,  4]=>2, [:when,  2,  6]=>0, [:else,  3,  2]=>1},
-        [:case,  4,  9] => {[:when,  5, 11]=>2, [:when,  6, 13]=>0, [:else,  7,  9]=>1},
-        [:case,  8, 16] => {[:when,  9, 18]=>2, [:when, 10, 20]=>0, [:else, 11, 22]=>1},
-        [:case, 12, 25] => {[:when, 13, 27]=>2, [:when, 14, 29]=>0, [:else, 15, 31]=>1},
+        [:case,  0,  2, 8] => {[:when,  1,  4, 10]=>2, [:when,  2,  6, 10]=>0, [:else,  3,  2,  8]=>1},
+        [:case,  4,  9, 8] => {[:when,  5, 11, 10]=>2, [:when,  6, 13, 10]=>0, [:else,  7,  9,  8]=>1},
+        [:case,  8, 16, 8] => {[:when,  9, 18, 10]=>2, [:when, 10, 20, 10]=>0, [:else, 11, 22, 10]=>1},
+        [:case, 12, 25, 8] => {[:when, 13, 27, 10]=>2, [:when, 14, 29, 10]=>0, [:else, 15, 31, 10]=>1},
       }
     }
     assert_coverage(<<-"end;", { branches: true }, result)
@@ -293,8 +293,8 @@ class TestCoverage < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/coverage/test_coverage.rb#L293
   def test_branch_coverage_for_safe_method_invocation
     result = {
       :branches=>{
-        [:"&.", 0, 3] => {[:then, 1, 3]=>1, [:else, 2, 3]=>0},
-        [:"&.", 3, 4] => {[:then, 4, 4]=>0, [:else, 5, 4]=>1},
+        [:"&.", 0, 3, 6] => {[:then, 1, 3, 6]=>1, [:else, 2, 3, 6]=>0},
+        [:"&.", 3, 4, 6] => {[:then, 4, 4, 6]=>0, [:else, 5, 4, 6]=>1},
       }
     }
     assert_coverage(<<-"end;", { branches: true }, result)
Index: compile.c
===================================================================
--- compile.c	(revision 60361)
+++ compile.c	(revision 60362)
@@ -251,7 +251,7 @@ struct iseq_compile_data_ensure_node_sta https://github.com/ruby/ruby/blob/trunk/compile.c#L251
 	  ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(COVERAGE_INDEX_LINES)); \
       } \
   } while (0)
-#define DECL_BRANCH_BASE(branches, line, type) \
+#define DECL_BRANCH_BASE(branches, line, column, type) \
   do { \
       if (ISEQ_COVERAGE(iseq) && \
 	  ISEQ_BRANCH_COVERAGE(iseq) && \
@@ -261,9 +261,10 @@ struct iseq_compile_data_ensure_node_sta https://github.com/ruby/ruby/blob/trunk/compile.c#L261
 	  rb_ary_push(structure, branches); \
 	  rb_ary_push(branches, ID2SYM(rb_intern(type))); \
 	  rb_ary_push(branches, INT2FIX(line)); \
+	  rb_ary_push(branches, INT2FIX(column)); \
       } \
   } while (0)
-#define ADD_TRACE_BRANCH_COVERAGE(seq, line, type, branches) \
+#define ADD_TRACE_BRANCH_COVERAGE(seq, line, column, type, branches) \
   do { \
       if (ISEQ_COVERAGE(iseq) && \
 	  ISEQ_BRANCH_COVERAGE(iseq) && \
@@ -273,6 +274,7 @@ struct iseq_compile_data_ensure_node_sta https://github.com/ruby/ruby/blob/trunk/compile.c#L274
 	  rb_ary_push(counters, INT2FIX(0)); \
 	  rb_ary_push(branches, ID2SYM(rb_intern(type))); \
 	  rb_ary_push(branches, INT2FIX(line)); \
+	  rb_ary_push(branches, INT2FIX(column)); \
 	  rb_ary_push(branches, INT2FIX(counter_idx)); \
 	  ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(counter_idx * 16 + COVERAGE_INDEX_BRANCHES)); \
       } \
@@ -4258,6 +4260,7 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR https://github.com/ruby/ruby/blob/trunk/compile.c#L4260
     NODE *node_else = type == NODE_IF ? node->nd_else : node->nd_body;
 
     const int line = nd_line(node);
+    const int column = nd_column(node);
     DECL_ANCHOR(cond_seq);
     DECL_ANCHOR(then_seq);
     DECL_ANCHOR(else_seq);
@@ -4279,13 +4282,13 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR https://github.com/ruby/ruby/blob/trunk/compile.c#L4282
     ADD_SEQ(ret, cond_seq);
 
     if (then_label->refcnt && else_label->refcnt) {
-	DECL_BRANCH_BASE(branches, line, type == NODE_IF ? "if" : "unless");
+	DECL_BRANCH_BASE(branches, line, column, type == NODE_IF ? "if" : "unless");
     }
 
     if (then_label->refcnt) {
 	ADD_LABEL(ret, then_label);
 	if (else_label->refcnt) {
-	    ADD_TRACE_BRANCH_COVERAGE(ret, node_body ? nd_line(node_body) : line, type == NODE_IF ? "then" : "else", branches);
+	    ADD_TRACE_BRANCH_COVERAGE(ret, node_body ? nd_line(node_body) : line, node_body ? nd_column(node_body) : column, type == NODE_IF ? "then" : "else", branches);
 	}
 	ADD_SEQ(ret, then_seq);
 	end_label = NEW_LABEL(line);
@@ -4295,7 +4298,7 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR https://github.com/ruby/ruby/blob/trunk/compile.c#L4298
     if (else_label->refcnt) {
 	ADD_LABEL(ret, else_label);
 	if (then_label->refcnt) {
-	    ADD_TRACE_BRANCH_COVERAGE(ret, node_else ? nd_line(node_else) : line, type == NODE_IF ? "else" : "then", branches);
+	    ADD_TRACE_BRANCH_COVERAGE(ret, node_else ? nd_line(node_else) : line, node_else ? nd_column(node_else) : column, type == NODE_IF ? "else" : "then", branches);
 	}
 	ADD_SEQ(ret, else_seq);
     }
@@ -4318,7 +4321,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4321
     DECL_ANCHOR(cond_seq);
     int only_special_literals = 1;
     VALUE literals = rb_hash_new();
-    int line;
+    int line, column;
     enum node_type type;
     VALUE branches = 0;
 
@@ -4334,11 +4337,12 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4337
     }
     CHECK(COMPILE(head, "case base", node->nd_head));
 
-    DECL_BRANCH_BASE(branches, nd_line(node), "case");
+    DECL_BRANCH_BASE(branches, nd_line(node), nd_column(node), "case");
 
     node = node->nd_body;
     type = nd_type(node);
     line = nd_line(node);
+    column = nd_column(node);
 
     if (type != NODE_WHEN) {
 	COMPILE_ERROR(ERROR_ARGS "NODE_CASE: unexpected node. must be NODE_WHEN, but %s", ruby_node_name(type));
@@ -4356,7 +4360,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4360
 	l1 = NEW_LABEL(line);
 	ADD_LABEL(body_seq, l1);
 	ADD_INSN(body_seq, line, pop);
-	ADD_TRACE_BRANCH_COVERAGE(body_seq, node->nd_body ? nd_line(node->nd_body) : line, "when", branches);
+	ADD_TRACE_BRANCH_COVERAGE(body_seq, node->nd_body ? nd_line(node->nd_body) : line, node->nd_body ? nd_column(node->nd_body) : column, "when", branches);
 	CHECK(COMPILE_(body_seq, "when body", node->nd_body, popped));
 	ADD_INSNL(body_seq, line, jump, endlabel);
 
@@ -4389,12 +4393,13 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4393
 	}
 	type = nd_type(node);
 	line = nd_line(node);
+	column = nd_column(node);
     }
     /* else */
     if (node) {
 	ADD_LABEL(cond_seq, elselabel);
 	ADD_INSN(cond_seq, line, pop);
-	ADD_TRACE_BRANCH_COVERAGE(cond_seq, nd_line(node), "else", branches);
+	ADD_TRACE_BRANCH_COVERAGE(cond_seq, nd_line(node), nd_column(node), "else", branches);
 	CHECK(COMPILE_(cond_seq, "else", node, popped));
 	ADD_INSNL(cond_seq, line, jump, endlabel);
     }
@@ -4402,7 +4407,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4407
 	debugs("== else (implicit)\n");
 	ADD_LABEL(cond_seq, elselabel);
 	ADD_INSN(cond_seq, nd_line(tempnode), pop);
-	ADD_TRACE_BRANCH_COVERAGE(cond_seq, nd_line(tempnode), "else", branches);
+	ADD_TRACE_BRANCH_COVERAGE(cond_seq, nd_line(tempnode), nd_column(tempnode), "else", branches);
 	if (!popped) {
 	    ADD_INSN(cond_seq, nd_line(tempnode), putnil);
 	}
@@ -4433,16 +4438,17 @@ compile_when(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4438
     DECL_ANCHOR(body_seq);
     VALUE branches = 0;
 
-    DECL_BRANCH_BASE(branches, nd_line(node), "case");
+    DECL_BRANCH_BASE(branches, nd_line(node), nd_column(node), "case");
 
     INIT_ANCHOR(body_seq);
     endlabel = NEW_LABEL(nd_line(node));
 
     while (node && nd_type(node) == NODE_WHEN) {
 	const int line = nd_line(node);
+	const int column = nd_column(node);
 	LABEL *l1 = NEW_LABEL(line);
 	ADD_LABEL(body_seq, l1);
-	ADD_TRACE_BRANCH_COVERAGE(body_seq, node->nd_body ? nd_line(node->nd_body) : line, "when", branches);
+	ADD_TRACE_BRANCH_COVERAGE(body_seq, node->nd_body ? nd_line(node->nd_body) : line, node->nd_body ? nd_column(node->nd_body) : column, "when", branches);
 	CHECK(COMPILE_(body_seq, "when", node->nd_body, popped));
 	ADD_INSNL(body_seq, line, jump, endlabel);
 
@@ -4474,7 +4480,7 @@ compile_when(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4480
 	node = node->nd_next;
     }
     /* else */
-    ADD_TRACE_BRANCH_COVERAGE(ret, node ? nd_line(node) : nd_line(orig_node), "else", branches);
+    ADD_TRACE_BRANCH_COVERAGE(ret, node ? nd_line(node) : nd_line(orig_node), node ? nd_column(node) : nd_column(orig_node), "else", branches);
     CHECK(COMPILE_(ret, "else", node, popped));
     ADD_INSNL(ret, nd_line(orig_node), jump, endlabel);
 
@@ -4487,6 +4493,7 @@ static int https://github.com/ruby/ruby/blob/trunk/compile.c#L4493
 compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped, const enum node_type type)
 {
     const int line = (int)nd_line(node);
+    const int column = nd_column(node);
     LABEL *prev_start_label = ISEQ_COMPILE_DATA(iseq)->start_label;
     LABEL *prev_end_label = ISEQ_COMPILE_DATA(iseq)->end_label;
     LABEL *prev_redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label;
@@ -4522,8 +4529,8 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4529
     if (tmp_label) ADD_LABEL(ret, tmp_label);
 
     ADD_LABEL(ret, redo_label);
-    DECL_BRANCH_BASE(branches, line, type == NODE_WHILE ? "while" : "until");
-    ADD_TRACE_BRANCH_COVERAGE(ret, node->nd_body ? nd_line(node->nd_body) : line, "body", branches);
+    DECL_BRANCH_BASE(branches, line, column, type == NODE_WHILE ? "while" : "until");
+    ADD_TRACE_BRANCH_COVERAGE(ret, node->nd_body ? nd_line(node->nd_body) : line, node->nd_body ? nd_column(node->nd_body) : column, "body", branches);
     CHECK(COMPILE_POPPED(ret, "while body", node->nd_body));
     ADD_LABEL(ret, next_label);	/* next */
 
@@ -5723,10 +5730,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK https://github.com/ruby/ruby/blob/trunk/compile.c#L5730
 		else_label = NEW_LABEL(line);
 		end_label = NEW_LABEL(line);
 
-		DECL_BRANCH_BASE(branches, nd_line(node), "&.");
+		DECL_BRANCH_BASE(branches, nd_line(node), nd_column(node), "&.");
 		ADD_INSN(recv, line, dup);
 		ADD_INSNL(recv, line, branchnil, else_label);
-		ADD_TRACE_BRANCH_COVERAGE(recv, nd_line(node), "then", branches);
+		ADD_TRACE_BRANCH_COVERAGE(recv, nd_line(node), nd_column(node), "then", branches);
 	    }
 	}
 	else if (type == NODE_FCALL || type == NODE_VCALL) {
@@ -5761,7 +5768,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK https://github.com/ruby/ruby/blob/trunk/compile.c#L5768
 	if (else_label && end_label) {
 	    ADD_INSNL(ret, line, jump, end_label);
 	    ADD_LABEL(ret, else_label);
-	    ADD_TRACE_BRANCH_COVERAGE(ret, nd_line(node), "else", branches);
+	    ADD_TRACE_BRANCH_COVERAGE(ret, nd_line(node), nd_column(node), "else", branches);
 	    ADD_LABEL(ret, end_label);
 	}
 	if (popped) {

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

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