]> Cypherpunks repositories - gostls13.git/commitdiff
go/printer: simplify handling of line directives
authorRobert Griesemer <gri@golang.org>
Fri, 9 Mar 2018 00:06:16 +0000 (16:06 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 9 Mar 2018 01:01:25 +0000 (01:01 +0000)
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>
src/go/printer/printer.go
src/go/printer/printer_test.go
src/go/printer/testdata/comments.golden
src/go/printer/testdata/comments.input

index dbb4bbd90cf205cfbc9304b23ca63ccb81803f71..99c020d9fa8f5664d4e17ec6b35b5c277c775c6d 100644 (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
index e06604a407e9ae1fcd8a5f35fa0d8fd6acd0eda4..79c4f11e436c59a59cf1663dad5f065960ab8b89 100644 (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 {
index e1818e5fd53042bf3148a79d6abcb0b1f4754301..b91e79dbf2886c80abd2c95647683c4e4b2d4dbb 100644 (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
 }
 
index f3eda12c22959cbe7834645c173adba21bc48f2b..18337a4995af527775723f4b8170cf318921505f 100644 (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
 }