go.tools/cmd/cover: don't assume code is gofmt'd

We want to make an if look like two blocks and have the coverage
report for the else block decorate the "else" keyword with the right
color. To do this, we adjust the apparent starting point of the else
block to include the "else".

The previous code assumed the way to do this was to move the
width of "else " backwards from the else block's opening brace, but
that assumes there is a space there. Instead, we now just start the
else block exactly at the end of the if block. Simpler, cleaner, and
fixes a bug.

Fixes golang/go#8557.

LGTM=gri
R=gri
CC=golang-codereviews
https://golang.org/cl/127620043
This commit is contained in:
Rob Pike 2014-08-20 11:14:50 -07:00
parent c21a767b2c
commit f11381f265
1 changed files with 11 additions and 4 deletions

View File

@ -195,17 +195,16 @@ func (f *File) Visit(node ast.Node) ast.Visitor {
// if y {
// }
// }
const backupToElse = token.Pos(len("else ")) // The AST doesn't remember the else location. We can make an accurate guess.
switch stmt := n.Else.(type) {
case *ast.IfStmt:
block := &ast.BlockStmt{
Lbrace: stmt.If - backupToElse, // So the covered part looks like it starts at the "else".
Lbrace: n.Body.End(), // Start at end of the "if" block so the covered part looks like it starts at the "else".
List: []ast.Stmt{stmt},
Rbrace: stmt.End(),
}
n.Else = block
case *ast.BlockStmt:
stmt.Lbrace -= backupToElse // So the block looks like it starts at the "else".
stmt.Lbrace = n.Body.End() // Start at end of the "if" block so the covered part looks like it starts at the "else".
default:
panic("unexpected node type in if")
}
@ -584,6 +583,11 @@ func (b blockSlice) Len() int { return len(b) }
func (b blockSlice) Less(i, j int) bool { return b[i].startByte < b[j].startByte }
func (b blockSlice) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
// offset translates a token position into a 0-indexed byte offset.
func (f *File) offset(pos token.Pos) int {
return f.fset.Position(pos).Offset
}
// addVariables adds to the end of the file the declarations to set up the counter and position variables.
func (f *File) addVariables(w io.Writer) {
// Self-check: Verify that the instrumented basic blocks are disjoint.
@ -596,7 +600,10 @@ func (f *File) addVariables(w io.Writer) {
for i := 1; i < len(t); i++ {
if t[i-1].endByte > t[i].startByte {
fmt.Fprintf(os.Stderr, "cover: internal error: block %d overlaps block %d\n", t[i-1].index, t[i].index)
fmt.Fprintf(os.Stderr, "\t%s:#%d,#%d %s:#%d,#%d\n", f.name, t[i-1].startByte, t[i-1].endByte, f.name, t[i].startByte, t[i].endByte)
// Note: error message is in byte positions, not token positions.
fmt.Fprintf(os.Stderr, "\t%s:#%d,#%d %s:#%d,#%d\n",
f.name, f.offset(t[i-1].startByte), f.offset(t[i-1].endByte),
f.name, f.offset(t[i].startByte), f.offset(t[i].endByte))
}
}