1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 // In an ErrorList, an error is represented by an *Error.
15 // The position Pos, if valid, points to the beginning of
16 // the offending token, and the error condition is described
24 // Error implements the error interface.
25 func (e Error
) Error() string {
26 if e
.Pos
.Filename
!= "" || e
.Pos
.IsValid() {
27 // don't print "<unknown position>"
28 // TODO(gri) reconsider the semantics of Position.IsValid
29 return e
.Pos
.String() + ": " + e
.Msg
34 // ErrorList is a list of *Errors.
35 // The zero value for an ErrorList is an empty ErrorList ready to use.
37 type ErrorList
[]*Error
39 // Add adds an Error with given position and error message to an ErrorList.
40 func (p
*ErrorList
) Add(pos token
.Position
, msg
string) {
41 *p
= append(*p
, &Error
{pos
, msg
})
44 // Reset resets an ErrorList to no errors.
45 func (p
*ErrorList
) Reset() { *p
= (*p
)[0:0] }
47 // ErrorList implements the sort Interface.
48 func (p ErrorList
) Len() int { return len(p
) }
49 func (p ErrorList
) Swap(i
, j
int) { p
[i
], p
[j
] = p
[j
], p
[i
] }
51 func (p ErrorList
) Less(i
, j
int) bool {
54 // Note that it is not sufficient to simply compare file offsets because
55 // the offsets do not reflect modified line information (through //line
57 if e
.Filename
!= f
.Filename
{
58 return e
.Filename
< f
.Filename
61 return e
.Line
< f
.Line
63 if e
.Column
!= f
.Column
{
64 return e
.Column
< f
.Column
66 return p
[i
].Msg
< p
[j
].Msg
69 // Sort sorts an ErrorList. *Error entries are sorted by position,
70 // other errors are sorted by error message, and before any *Error
73 func (p ErrorList
) Sort() {
77 // RemoveMultiples sorts an ErrorList and removes all but the first error per line.
78 func (p
*ErrorList
) RemoveMultiples() {
80 var last token
.Position
// initial last.Line is != any legal error line
82 for _
, e
:= range *p
{
83 if e
.Pos
.Filename
!= last
.Filename || e
.Pos
.Line
!= last
.Line
{
92 // An ErrorList implements the error interface.
93 func (p ErrorList
) Error() string {
100 return fmt
.Sprintf("%s (and %d more errors)", p
[0], len(p
)-1)
103 // Err returns an error equivalent to this error list.
104 // If the list is empty, Err returns nil.
105 func (p ErrorList
) Err() error
{
112 // PrintError is a utility function that prints a list of errors to w,
113 // one error per line, if the err parameter is an ErrorList. Otherwise
114 // it prints the err string.
116 func PrintError(w io
.Writer
, err error
) {
117 if list
, ok
:= err
.(ErrorList
); ok
{
118 for _
, e
:= range list
{
119 fmt
.Fprintf(w
, "%s\n", e
)
121 } else if err
!= nil {
122 fmt
.Fprintf(w
, "%s\n", err
)