1
0
mirror of https://github.com/golang/go synced 2024-11-07 22:56:15 -07:00

go/scanner: continue adding directory to file name

Before CL 97795, when go/scanner saw a //line comment, it would clean
the path and, if the path was relative, prepend the directory from the
file name. This was not the best API because it meant that the
behavior changed based on whether the code was running on Windows or
not, and it meant that information from the //line directive was lost.
So in CL 97795, among other changes, go/scanner was changed to simply
return the filename given in the //line comment.

Unfortunately existing tools such as unparam and unconvert expected
the old behavior. In order to avoid breaking those tools, revert that
part of the change.

Fixes #26671

Change-Id: Ifa06542bd19cda9d682ac33766ab9080444ba050
Reviewed-on: https://go-review.googlesource.com/127658
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Ian Lance Taylor 2018-08-02 12:35:32 -07:00
parent 8589f46fe0
commit d6597ade89
2 changed files with 38 additions and 4 deletions

View File

@ -259,6 +259,14 @@ func (s *Scanner) updateLineInfo(next, offs int, text []byte) {
filename := string(text[:i-1]) // lop off ":line", and trim white space filename := string(text[:i-1]) // lop off ":line", and trim white space
if filename == "" && ok2 { if filename == "" && ok2 {
filename = s.file.Position(s.file.Pos(offs)).Filename filename = s.file.Position(s.file.Pos(offs)).Filename
} else if filename != "" {
// Put a relative filename in the current directory.
// This is for compatibility with earlier releases.
// See issue 26671.
filename = filepath.Clean(filename)
if !filepath.IsAbs(filename) {
filename = filepath.Join(s.dir, filename)
}
} }
s.file.AddLineColumnInfo(next, filename, line, col) s.file.AddLineColumnInfo(next, filename, line, col)

View File

@ -9,6 +9,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"testing" "testing"
) )
@ -204,7 +205,9 @@ func newlineCount(s string) int {
func checkPos(t *testing.T, lit string, p token.Pos, expected token.Position) { func checkPos(t *testing.T, lit string, p token.Pos, expected token.Position) {
pos := fset.Position(p) pos := fset.Position(p)
if pos.Filename != expected.Filename { // Check cleaned filenames so that we don't have to worry about
// different os.PathSeparator values.
if pos.Filename != expected.Filename && filepath.Clean(pos.Filename) != filepath.Clean(expected.Filename) {
t.Errorf("bad filename for %q: got %s, expected %s", lit, pos.Filename, expected.Filename) t.Errorf("bad filename for %q: got %s, expected %s", lit, pos.Filename, expected.Filename)
} }
if pos.Offset != expected.Offset { if pos.Offset != expected.Offset {
@ -520,7 +523,7 @@ var segments = []segment{
{"\n //line foo:42\n line43", "foo\t", 44, 0}, // bad line comment, ignored (use existing, prior filename) {"\n //line foo:42\n line43", "foo\t", 44, 0}, // bad line comment, ignored (use existing, prior filename)
{"\n//line foo 42\n line44", "foo\t", 46, 0}, // bad line comment, ignored (use existing, prior filename) {"\n//line foo 42\n line44", "foo\t", 46, 0}, // bad line comment, ignored (use existing, prior filename)
{"\n//line /bar:42\n line45", "/bar", 42, 0}, {"\n//line /bar:42\n line45", "/bar", 42, 0},
{"\n//line ./foo:42\n line46", "./foo", 42, 0}, {"\n//line ./foo:42\n line46", "foo", 42, 0},
{"\n//line a/b/c/File1.go:100\n line100", "a/b/c/File1.go", 100, 0}, {"\n//line a/b/c/File1.go:100\n line100", "a/b/c/File1.go", 100, 0},
{"\n//line c:\\bar:42\n line200", "c:\\bar", 42, 0}, {"\n//line c:\\bar:42\n line200", "c:\\bar", 42, 0},
{"\n//line c:\\dir\\File1.go:100\n line201", "c:\\dir\\File1.go", 100, 0}, {"\n//line c:\\dir\\File1.go:100\n line201", "c:\\dir\\File1.go", 100, 0},
@ -539,9 +542,32 @@ var segments = []segment{
{"\n/*line foo:100:10*/\n\nf2", "foo", 102, 1}, // absolute column since on new line {"\n/*line foo:100:10*/\n\nf2", "foo", 102, 1}, // absolute column since on new line
} }
var dirsegments = []segment{
// exactly one token per line since the test consumes one token per segment
{" line1", "TestLineDir/TestLineDirectives", 1, 3},
{"\n//line File1.go:100\n line100", "TestLineDir/File1.go", 100, 0},
}
var dirUnixSegments = []segment{
{"\n//line /bar:42\n line42", "/bar", 42, 0},
}
var dirWindowsSegments = []segment{
{"\n//line c:\\bar:42\n line42", "c:\\bar", 42, 0},
}
// Verify that line directives are interpreted correctly. // Verify that line directives are interpreted correctly.
func TestLineDirectives(t *testing.T) { func TestLineDirectives(t *testing.T) {
// make source testSegments(t, segments, "TestLineDirectives")
testSegments(t, dirsegments, "TestLineDir/TestLineDirectives")
if runtime.GOOS == "windows" {
testSegments(t, dirWindowsSegments, "TestLineDir/TestLineDirectives")
} else {
testSegments(t, dirUnixSegments, "TestLineDir/TestLineDirectives")
}
}
func testSegments(t *testing.T, segments []segment, filename string) {
var src string var src string
for _, e := range segments { for _, e := range segments {
src += e.srcline src += e.srcline
@ -549,7 +575,7 @@ func TestLineDirectives(t *testing.T) {
// verify scan // verify scan
var S Scanner var S Scanner
file := fset.AddFile("TestLineDirectives", fset.Base(), len(src)) file := fset.AddFile(filename, fset.Base(), len(src))
S.Init(file, []byte(src), func(pos token.Position, msg string) { t.Error(Error{pos, msg}) }, dontInsertSemis) S.Init(file, []byte(src), func(pos token.Position, msg string) { t.Error(Error{pos, msg}) }, dontInsertSemis)
for _, s := range segments { for _, s := range segments {
p, _, lit := S.Scan() p, _, lit := S.Scan()