1
0
mirror of https://github.com/golang/go synced 2024-11-23 18:20:04 -07:00

go/printer: simplify handling of line directives

Strangely enough, the existing implementation used adjusted (by line
directives) source positions to determine layout and thus required
position corrections when printing a line directive.

Instead, just use the unadjusted, absolute source positions and then
printing a line directive doesn't require any adjustments, only some
care to make sure it remains in column 1 as before.

The new code doesn't need to parse line directives anymore and simply
ensures that comments with the //line prefix and starting in column 1
remain in that position. That is a slight change from the old behavior
(which ignored incorrect line directives, e.g. because they had an
invalid line number) but unlikely to show up in real code.

This is prep work for handling of line directives that also specify
columns (which now won't require much special handling anymore).

For #24143.

Change-Id: I07eb2e1b35b37337e632e3dbf5b70c783c615f8a
Reviewed-on: https://go-review.googlesource.com/99621
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Robert Griesemer 2018-03-08 16:06:16 -08:00
parent 2cc15b18db
commit 53c416396f
4 changed files with 13 additions and 25 deletions

View File

@ -11,7 +11,6 @@ import (
"go/token"
"io"
"os"
"strconv"
"strings"
"text/tabwriter"
"unicode"
@ -192,13 +191,13 @@ func (p *printer) linesFrom(line int) int {
func (p *printer) posFor(pos token.Pos) token.Position {
// not used frequently enough to cache entire token.Position
return p.fset.Position(pos)
return p.fset.PositionFor(pos, false /* absolute position */)
}
func (p *printer) lineFor(pos token.Pos) int {
if pos != p.cachedPos {
p.cachedPos = pos
p.cachedLine = p.fset.Position(pos).Line
p.cachedLine = p.fset.PositionFor(pos, false /* absolute position */).Line
}
return p.cachedLine
}
@ -622,24 +621,10 @@ func (p *printer) writeComment(comment *ast.Comment) {
const linePrefix = "//line "
if strings.HasPrefix(text, linePrefix) && (!pos.IsValid() || pos.Column == 1) {
// possibly a line directive
ldir := strings.TrimSpace(text[len(linePrefix):])
if i := strings.LastIndex(ldir, ":"); i >= 0 {
if line, err := strconv.Atoi(ldir[i+1:]); err == nil && line > 0 {
// The line directive we are about to print changed
// the Filename and Line number used for subsequent
// tokens. We have to update our AST-space position
// accordingly and suspend indentation temporarily.
indent := p.indent
p.indent = 0
defer func() {
p.pos.Filename = ldir[:i]
p.pos.Line = line
p.pos.Column = 1
p.indent = indent
}()
}
}
// Possibly a //-style line directive.
// Suspend indentation temporarily to keep line directive valid.
defer func(indent int) { p.indent = indent }(p.indent)
p.indent = 0
}
// shortcut common case of //-style comments

View File

@ -325,7 +325,7 @@ func fibo(n int) {
comment := f.Comments[0].List[0]
pos := comment.Pos()
if fset.Position(pos).Offset != 1 {
if fset.PositionFor(pos, false /* absolute position */).Offset != 1 {
t.Error("expected offset 1") // error in test
}
@ -422,6 +422,7 @@ func (t *t) foo(a, b, c int) int {
t.Errorf("got ident %s; want %s", i2.Name, i1.Name)
}
// here we care about the relative (line-directive adjusted) positions
l1 := fset.Position(i1.Pos()).Line
l2 := fset.Position(i2.Pos()).Line
if l2 != l1 {

View File

@ -702,8 +702,9 @@ func _() {
//line foo:2
_ = 2
// The following is not a legal line directive (negative line number):
//line foo:-3
// The following is not a legal line directive (negative line number), but
// it looks like one, so don't indent it:
//line foo:-3
_ = 3
}

View File

@ -699,7 +699,8 @@ func _() {
//line foo:2
_ = 2
// The following is not a legal line directive (negative line number):
// The following is not a legal line directive (negative line number), but
// it looks like one, so don't indent it:
//line foo:-3
_ = 3
}