]> Cypherpunks repositories - gostls13.git/commitdiff
go/scanner: interpret filenames in //line filename:line comments
authorRobert Griesemer <gri@golang.org>
Fri, 17 Dec 2010 21:54:37 +0000 (13:54 -0800)
committerRobert Griesemer <gri@golang.org>
Fri, 17 Dec 2010 21:54:37 +0000 (13:54 -0800)
    relative to the source file directory

R=r, rsc
CC=golang-dev
https://golang.org/cl/3752041

src/pkg/go/scanner/scanner.go
src/pkg/go/scanner/scanner_test.go

index 4374dec7285d86a34997f6ec92a29f641484107d..6ce846cd8a31413ca28938cb54cbd896351f448d 100644 (file)
@@ -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
                        }
                }
        }
index edaeb1fd2e4e056c55d430745be943eb8aa4cb74..b1004f89d21c72074ff020575b1f9392ad126f45 100644 (file)
@@ -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)