aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/syntax/scanner.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2016-11-30 23:28:40 -0800
committerRobert Griesemer <gri@golang.org>2016-12-09 00:43:04 +0000
commit32bf2829a17a90bdbd472335707639ba35776da6 (patch)
treed40b974e80f953388fee9320a53fcde833e6e2fb /src/cmd/compile/internal/syntax/scanner.go
parent8d20b25779d4ce32e8eaeb52374fba1e74f7df57 (diff)
downloadgo-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.go71
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() {