diff --git a/doc/go1.html b/doc/go1.html index e3d2354e64..7613c38805 100644 --- a/doc/go1.html +++ b/doc/go1.html @@ -1041,6 +1041,16 @@ useful for scanning text other then Go source files. Instead, the for that purpose.
+
+The ErrorHandler provided
+to the scanner's Init method is
+now simply a function rather than an interface. The ErrorVector type has
+been removed in favor of the (existing) ErrorList
+type, and the ErrorVector methods have been migrated. Instead of embedding
+an ErrorVector in a client of the scanner, now a client should maintain
+an ErrorList.
+
The set of parse functions provided by the go/parser
package has been reduced to the primary parse function
diff --git a/doc/go1.tmpl b/doc/go1.tmpl
index 8f27682780..f6e69e6ca2 100644
--- a/doc/go1.tmpl
+++ b/doc/go1.tmpl
@@ -944,6 +944,16 @@ useful for scanning text other then Go source files. Instead, the
for that purpose.
+The ErrorHandler provided
+to the scanner's Init method is
+now simply a function rather than an interface. The ErrorVector type has
+been removed in favor of the (existing) ErrorList
+type, and the ErrorVector methods have been migrated. Instead of embedding
+an ErrorVector in a client of the scanner, now a client should maintain
+an ErrorList.
+
The set of parse functions provided by the go/parser
package has been reduced to the primary parse function
diff --git a/src/pkg/exp/types/check.go b/src/pkg/exp/types/check.go
index 09e29d1261..ae0beb4e9b 100644
--- a/src/pkg/exp/types/check.go
+++ b/src/pkg/exp/types/check.go
@@ -17,14 +17,14 @@ import (
const debug = false
type checker struct {
- fset *token.FileSet
- scanner.ErrorVector
- types map[ast.Expr]Type
+ fset *token.FileSet
+ errors scanner.ErrorList
+ types map[ast.Expr]Type
}
func (c *checker) errorf(pos token.Pos, format string, args ...interface{}) string {
msg := fmt.Sprintf(format, args...)
- c.Error(c.fset.Position(pos), msg)
+ c.errors.Add(c.fset.Position(pos), msg)
return msg
}
@@ -221,5 +221,6 @@ func Check(fset *token.FileSet, pkg *ast.Package) (types map[ast.Expr]Type, err
c.checkObj(obj, false)
}
- return c.types, c.GetError(scanner.NoMultiples)
+ c.errors.RemoveMultiples()
+ return c.types, c.errors.Err()
}
diff --git a/src/pkg/go/ast/resolve.go b/src/pkg/go/ast/resolve.go
index c7c8e7c101..908e61c5da 100644
--- a/src/pkg/go/ast/resolve.go
+++ b/src/pkg/go/ast/resolve.go
@@ -14,12 +14,12 @@ import (
)
type pkgBuilder struct {
- scanner.ErrorVector
- fset *token.FileSet
+ fset *token.FileSet
+ errors scanner.ErrorList
}
func (p *pkgBuilder) error(pos token.Pos, msg string) {
- p.Error(p.fset.Position(pos), msg)
+ p.errors.Add(p.fset.Position(pos), msg)
}
func (p *pkgBuilder) errorf(pos token.Pos, format string, args ...interface{}) {
@@ -169,5 +169,6 @@ func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer,
pkgScope.Outer = universe // reset universe scope
}
- return &Package{pkgName, pkgScope, imports, files}, p.GetError(scanner.Sorted)
+ p.errors.Sort()
+ return &Package{pkgName, pkgScope, imports, files}, p.errors.Err()
}
diff --git a/src/pkg/go/parser/interface.go b/src/pkg/go/parser/interface.go
index f1b4ce34d1..5c203a7846 100644
--- a/src/pkg/go/parser/interface.go
+++ b/src/pkg/go/parser/interface.go
@@ -80,13 +80,25 @@ const (
// are returned via a scanner.ErrorList which is sorted by file position.
//
func ParseFile(fset *token.FileSet, filename string, src interface{}, mode Mode) (*ast.File, error) {
+ // get source
text, err := readSource(filename, src)
if err != nil {
return nil, err
}
+
+ // parse source
var p parser
p.init(fset, filename, text, mode)
- return p.parseFile(), p.errors()
+ f := p.parseFile()
+
+ // sort errors
+ if p.mode&SpuriousErrors == 0 {
+ p.errors.RemoveMultiples()
+ } else {
+ p.errors.Sort()
+ }
+
+ return f, p.errors.Err()
}
// ParseDir calls ParseFile for the files in the directory specified by path and
diff --git a/src/pkg/go/parser/parser.go b/src/pkg/go/parser/parser.go
index 6bee8de9f6..e6dffa3709 100644
--- a/src/pkg/go/parser/parser.go
+++ b/src/pkg/go/parser/parser.go
@@ -18,8 +18,8 @@ import (
// The parser structure holds the parser's internal state.
type parser struct {
- file *token.File
- scanner.ErrorVector
+ file *token.File
+ errors scanner.ErrorList
scanner scanner.Scanner
// Tracing/debugging
@@ -58,7 +58,8 @@ func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mod
if mode&ParseComments != 0 {
m = scanner.ScanComments
}
- p.scanner.Init(p.file, src, p, m)
+ eh := func(pos token.Position, msg string) { p.errors.Add(pos, msg) }
+ p.scanner.Init(p.file, src, eh, m)
p.mode = mode
p.trace = mode&Trace != 0 // for convenience (p.trace is used frequently)
@@ -74,14 +75,6 @@ func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode Mod
p.openLabelScope()
}
-func (p *parser) errors() error {
- m := scanner.Sorted
- if p.mode&SpuriousErrors == 0 {
- m = scanner.NoMultiples
- }
- return p.GetError(m)
-}
-
// ----------------------------------------------------------------------------
// Scoping support
@@ -334,7 +327,7 @@ func (p *parser) next() {
}
func (p *parser) error(pos token.Pos, msg string) {
- p.Error(p.file.Position(pos), msg)
+ p.errors.Add(p.file.Position(pos), msg)
}
func (p *parser) errorExpected(pos token.Pos, msg string) {
@@ -2123,7 +2116,7 @@ func (p *parser) parseFile() *ast.File {
// Don't bother parsing the rest if we had errors already.
// Likely not a Go source file at all.
- if p.ErrorCount() == 0 && p.mode&PackageClauseOnly == 0 {
+ if p.errors.Len() == 0 && p.mode&PackageClauseOnly == 0 {
// import decls
for p.tok == token.IMPORT {
decls = append(decls, p.parseGenDecl(token.IMPORT, parseImportSpec))
diff --git a/src/pkg/go/scanner/errors.go b/src/pkg/go/scanner/errors.go
index cd9620b878..8a75a96508 100644
--- a/src/pkg/go/scanner/errors.go
+++ b/src/pkg/go/scanner/errors.go
@@ -11,44 +11,18 @@ import (
"sort"
)
-// An implementation of an ErrorHandler may be provided to the Scanner.
-// If a syntax error is encountered and a handler was installed, Error
-// is called with a position and an error message. The position points
-// to the beginning of the offending token.
-//
-type ErrorHandler interface {
- Error(pos token.Position, msg string)
-}
-
-// ErrorVector implements the ErrorHandler interface. It maintains a list
-// of errors which can be retrieved with GetErrorList and GetError. The
-// zero value for an ErrorVector is an empty ErrorVector ready to use.
-//
-// A common usage pattern is to embed an ErrorVector alongside a
-// scanner in a data structure that uses the scanner. By passing a
-// reference to an ErrorVector to the scanner's Init call, default
-// error handling is obtained.
-//
-type ErrorVector struct {
- errors []*Error
-}
-
-// Reset resets an ErrorVector to no errors.
-func (h *ErrorVector) Reset() { h.errors = h.errors[:0] }
-
-// ErrorCount returns the number of errors collected.
-func (h *ErrorVector) ErrorCount() int { return len(h.errors) }
-
-// Within ErrorVector, an error is represented by an Error node. The
-// position Pos, if valid, points to the beginning of the offending
-// token, and the error condition is described by Msg.
+// In an ErrorList, an error is represented by an *Error.
+// The position Pos, if valid, points to the beginning of
+// the offending token, and the error condition is described
+// by Msg.
//
type Error struct {
Pos token.Position
Msg string
}
-func (e *Error) Error() string {
+// Error implements the error interface.
+func (e Error) Error() string {
if e.Pos.Filename != "" || e.Pos.IsValid() {
// don't print "