2 // Copyright 2012 The Go Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file.
6 // This file implements various error reporters.
12 "cmd/compile/internal/syntax"
18 func unimplemented() {
19 panic("unimplemented")
24 panic("assertion failed")
32 func (check *Checker) qualifier(pkg *Package) string {
33 // Qualify the package unless it's the package being type-checked.
35 // If the same package name was used by multiple packages, display the full path.
36 if check.pkgCnt[pkg.name] > 1 {
37 return strconv.Quote(pkg.path)
44 func (check *Checker) sprintf(format string, args ...interface{}) string {
45 for i, arg := range args {
46 switch a := arg.(type) {
50 panic("internal error: should always pass *operand")
52 arg = operandString(a, check.qualifier)
58 arg = ObjectString(a, check.qualifier)
60 arg = TypeString(a, check.qualifier)
64 return fmt.Sprintf(format, args...)
67 func (check *Checker) trace(pos syntax.Pos, format string, args ...interface{}) {
68 fmt.Printf("%s:\t%s%s\n",
70 strings.Repeat(". ", check.indent),
71 check.sprintf(format, args...),
75 // dump is only needed for debugging
76 func (check *Checker) dump(format string, args ...interface{}) {
77 fmt.Println(check.sprintf(format, args...))
80 func (check *Checker) err(pos syntax.Pos, msg string, soft bool) {
81 // Cheap trick: Don't report errors with messages containing
82 // "invalid operand" or "invalid type" as those tend to be
83 // follow-on errors which don't add useful information. Only
84 // exclude them if these strings are not at the beginning,
85 // and only if we have at least one error already reported.
86 if check.firstErr != nil && (strings.Index(msg, "invalid operand") > 0 || strings.Index(msg, "invalid type") > 0) {
90 err := Error{pos, stripAnnotations(msg), msg, soft}
91 if check.firstErr == nil {
96 check.trace(pos, "ERROR: %s", msg)
101 panic(bailout{}) // report only first error
106 type poser interface {
110 func (check *Checker) error(at poser, msg string) {
111 check.err(posFor(at), msg, false)
114 func (check *Checker) errorf(at poser, format string, args ...interface{}) {
115 check.err(posFor(at), check.sprintf(format, args...), false)
118 func (check *Checker) softErrorf(at poser, format string, args ...interface{}) {
119 check.err(posFor(at), check.sprintf(format, args...), true)
122 func (check *Checker) invalidASTf(at poser, format string, args ...interface{}) {
123 check.errorf(at, "invalid AST: "+format, args...)
126 func (check *Checker) invalidArgf(at poser, format string, args ...interface{}) {
127 check.errorf(at, "invalid argument: "+format, args...)
130 func (check *Checker) invalidOpf(at poser, format string, args ...interface{}) {
131 check.errorf(at, "invalid operation: "+format, args...)
134 // posFor reports the left (= start) position of at.
135 func posFor(at poser) syntax.Pos {
136 switch x := at.(type) {
139 return startPos(x.expr)
147 // stripAnnotations removes internal (type) annotations from s.
148 func stripAnnotations(s string) string {
149 // Would like to use strings.Builder but it's not available in Go 1.4.
151 for _, r := range s {
152 // strip #'s and subscript digits
153 if r != instanceMarker && !('₀' <= r && r < '₀'+10) { // '₀' == U+2080
157 if b.Len() < len(s) {