diff options
author | Robert Griesemer <gri@golang.org> | 2016-11-30 23:28:40 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2016-12-09 00:43:04 +0000 |
commit | 32bf2829a17a90bdbd472335707639ba35776da6 (patch) | |
tree | d40b974e80f953388fee9320a53fcde833e6e2fb /src/cmd/compile/internal/syntax/scanner.go | |
parent | 8d20b25779d4ce32e8eaeb52374fba1e74f7df57 (diff) | |
download | go-32bf2829a17a90bdbd472335707639ba35776da6.tar.gz go-32bf2829a17a90bdbd472335707639ba35776da6.zip |
[dev.inline] cmd/compile/internal/syntax: process //line pragmas in scanner
Reviewed in and cherry-picked from https://go-review.googlesource.com/#/c/33764/.
Minor adjustment in noder.go to make merge compile again.
Change-Id: Ib5029b52b59944f207b0f2438c8a5aa576eb25b8
Reviewed-on: https://go-review.googlesource.com/34233
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/syntax/scanner.go')
-rw-r--r-- | src/cmd/compile/internal/syntax/scanner.go | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/src/cmd/compile/internal/syntax/scanner.go b/src/cmd/compile/internal/syntax/scanner.go index 978d7d2c0a..6fdc0dc6da 100644 --- a/src/cmd/compile/internal/syntax/scanner.go +++ b/src/cmd/compile/internal/syntax/scanner.go @@ -7,6 +7,7 @@ package syntax import ( "fmt" "io" + "strconv" "strings" "unicode" "unicode/utf8" @@ -18,6 +19,7 @@ type scanner struct { pragma Pragma // current token, valid after calling next() + base *PosBase line, col uint tok token lit string // valid if tok is _Name or _Literal @@ -28,9 +30,10 @@ type scanner struct { pragh PragmaHandler } -func (s *scanner) init(src io.Reader, errh ErrorHandler, pragh PragmaHandler) { +func (s *scanner) init(filename string, src io.Reader, errh ErrorHandler, pragh PragmaHandler) { s.source.init(src, errh) s.nlsemi = false + s.base = NewFileBase(filename) s.pragh = pragh } @@ -524,48 +527,70 @@ func (s *scanner) rune() { s.tok = _Literal } +func (s *scanner) skipLine(r rune) { + for r >= 0 { + if r == '\n' { + s.ungetr() // don't consume '\n' - needed for nlsemi logic + break + } + r = s.getr() + } +} + func (s *scanner) lineComment() { // recognize pragmas - var prefix string + prefix := "" r := s.getr() - if s.pragh == nil { - goto skip - } - switch r { case 'g': + if s.pragh == nil { + s.skipLine(r) + return + } prefix = "go:" case 'l': prefix = "line " default: - goto skip + s.skipLine(r) + return } - s.startLit() for _, m := range prefix { if r != m { - s.stopLit() - goto skip + s.skipLine(r) + return } r = s.getr() } - for r >= 0 { - if r == '\n' { - s.ungetr() - break + // pragma text without prefix and line ending (which may be "\r\n" if Windows) + s.startLit() + s.skipLine(r) + text := strings.TrimSuffix(string(s.stopLit()), "\r") + + // process //line filename:line pragma + if prefix[0] == 'l' { + // Want to use LastIndexByte below but it's not defined in Go1.4 and bootstrap fails. + i := strings.LastIndex(text, ":") // look from right (Windows filenames may contain ':') + if i < 0 { + return + } + nstr := text[i+1:] + n, err := strconv.Atoi(nstr) + if err != nil || n <= 0 || n > lineM { + s.error_at(s.line0, s.col0-uint(len(nstr)), "invalid line number: "+nstr) + return + } + s.base = NewLinePragmaBase(MakePos(s.base.Pos().Base(), s.line, s.col), text[:i], uint(n)) + // TODO(gri) Return here once we rely exclusively + // on node positions for line number information, + // and remove //line pragma handling elsewhere. + if s.pragh == nil { + return } - r = s.getr() } - s.pragma |= s.pragh(s.line, strings.TrimSuffix(string(s.stopLit()), "\r")) - return -skip: - // consume line - for r != '\n' && r >= 0 { - r = s.getr() - } - s.ungetr() // don't consume '\n' - needed for nlsemi logic + s.pragma |= s.pragh(s.line, prefix+text) } func (s *scanner) fullComment() { |