From: Robert Griesemer Date: Fri, 17 Dec 2010 21:54:37 +0000 (-0800) Subject: go/scanner: interpret filenames in //line filename:line comments X-Git-Tag: weekly.2010-12-22~7 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=8f68b23b8d847868c3ec3af3358a5ce9d3dd7b89;p=gostls13.git go/scanner: interpret filenames in //line filename:line comments relative to the source file directory R=r, rsc CC=golang-dev https://golang.org/cl/3752041 --- diff --git a/src/pkg/go/scanner/scanner.go b/src/pkg/go/scanner/scanner.go index 4374dec728..6ce846cd8a 100644 --- a/src/pkg/go/scanner/scanner.go +++ b/src/pkg/go/scanner/scanner.go @@ -22,6 +22,7 @@ package scanner import ( "bytes" "go/token" + "path" "strconv" "unicode" "utf8" @@ -35,6 +36,7 @@ import ( type Scanner struct { // immutable state file *token.File // source file handle + dir string // directory portion of file.Name() src []byte // source err ErrorHandler // error reporting; or nil mode uint // scanning mode @@ -111,6 +113,7 @@ const ( func (S *Scanner) Init(fset *token.FileSet, filename string, src []byte, err ErrorHandler, mode uint) *token.File { // Explicitly initialize all fields since a scanner may be reused. S.file = fset.AddFile(filename, fset.Base(), len(src)) + S.dir, _ = path.Split(filename) S.src = src S.err = err S.mode = mode @@ -174,8 +177,13 @@ func (S *Scanner) interpretLineComment(text []byte) { if i := bytes.Index(text, []byte{':'}); i > 0 { if line, err := strconv.Atoi(string(text[i+1:])); err == nil && line > 0 { // valid //line filename:line comment; + filename := path.Clean(string(text[len(prefix):i])) + if filename[0] != '/' { + // make filename relative to current directory + filename = path.Join(S.dir, filename) + } // update scanner position - S.file.AddLineInfo(S.lineOffset, string(text[len(prefix):i]), line-1) // -1 since comment applies to next line + S.file.AddLineInfo(S.lineOffset, filename, line-1) // -1 since comment applies to next line } } } diff --git a/src/pkg/go/scanner/scanner_test.go b/src/pkg/go/scanner/scanner_test.go index edaeb1fd2e..b1004f89d2 100644 --- a/src/pkg/go/scanner/scanner_test.go +++ b/src/pkg/go/scanner/scanner_test.go @@ -449,20 +449,20 @@ var segments = []struct { line int // line number for current token }{ // exactly one token per line since the test consumes one token per segment - {" line1", "TestLineComments", 1}, - {"\nline2", "TestLineComments", 2}, - {"\nline3 //line File1.go:100", "TestLineComments", 3}, // bad line comment, ignored - {"\nline4", "TestLineComments", 4}, - {"\n//line File1.go:100\n line100", "File1.go", 100}, - {"\n//line File2.go:200\n line200", "File2.go", 200}, - {"\n//line :1\n line1", "", 1}, - {"\n//line foo:42\n line42", "foo", 42}, - {"\n //line foo:42\n line44", "foo", 44}, // bad line comment, ignored - {"\n//line foo 42\n line46", "foo", 46}, // bad line comment, ignored - {"\n//line foo:42 extra text\n line48", "foo", 48}, // bad line comment, ignored - {"\n//line foo:42\n line42", "foo", 42}, - {"\n//line foo:42\n line42", "foo", 42}, - {"\n//line File1.go:100\n line100", "File1.go", 100}, + {" line1", "dir/TestLineComments", 1}, + {"\nline2", "dir/TestLineComments", 2}, + {"\nline3 //line File1.go:100", "dir/TestLineComments", 3}, // bad line comment, ignored + {"\nline4", "dir/TestLineComments", 4}, + {"\n//line File1.go:100\n line100", "dir/File1.go", 100}, + {"\n//line File2.go:200\n line200", "dir/File2.go", 200}, + {"\n//line :1\n line1", "dir", 1}, + {"\n//line foo:42\n line42", "dir/foo", 42}, + {"\n //line foo:42\n line44", "dir/foo", 44}, // bad line comment, ignored + {"\n//line foo 42\n line46", "dir/foo", 46}, // bad line comment, ignored + {"\n//line foo:42 extra text\n line48", "dir/foo", 48}, // bad line comment, ignored + {"\n//line /bar:42\n line42", "/bar", 42}, + {"\n//line ./foo:42\n line42", "dir/foo", 42}, + {"\n//line a/b/c/File1.go:100\n line100", "dir/a/b/c/File1.go", 100}, } @@ -476,7 +476,7 @@ func TestLineComments(t *testing.T) { // verify scan var S Scanner - file := S.Init(fset, "TestLineComments", []byte(src), nil, 0) + file := S.Init(fset, "dir/TestLineComments", []byte(src), nil, 0) for _, s := range segments { p, _, lit := S.Scan() pos := file.Position(p)