Commit 53c41639 authored by Robert Griesemer's avatar Robert Griesemer

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/99621Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 2cc15b18
......@@ -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
......
......@@ -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 {
......
......@@ -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
}
......
......@@ -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
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment