github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/go/types/errors.go (about) 1 // Copyright 2012 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. 4 5 // This file implements various error reporters. 6 7 package types 8 9 import ( 10 "fmt" 11 "go/ast" 12 "go/token" 13 "strings" 14 ) 15 16 func assert(p bool) { 17 if !p { 18 panic("assertion failed") 19 } 20 } 21 22 func unreachable() { 23 panic("unreachable") 24 } 25 26 func (check *Checker) qualifier(pkg *Package) string { 27 if pkg != check.pkg { 28 return pkg.path 29 } 30 return "" 31 } 32 33 func (check *Checker) sprintf(format string, args ...interface{}) string { 34 for i, arg := range args { 35 switch a := arg.(type) { 36 case nil: 37 arg = "<nil>" 38 case operand: 39 panic("internal error: should always pass *operand") 40 case *operand: 41 arg = operandString(a, check.qualifier) 42 case token.Pos: 43 arg = check.fset.Position(a).String() 44 case ast.Expr: 45 arg = ExprString(a) 46 case Object: 47 arg = ObjectString(a, check.qualifier) 48 case Type: 49 arg = TypeString(a, check.qualifier) 50 } 51 args[i] = arg 52 } 53 return fmt.Sprintf(format, args...) 54 } 55 56 func (check *Checker) trace(pos token.Pos, format string, args ...interface{}) { 57 fmt.Printf("%s:\t%s%s\n", 58 check.fset.Position(pos), 59 strings.Repeat(". ", check.indent), 60 check.sprintf(format, args...), 61 ) 62 } 63 64 // dump is only needed for debugging 65 func (check *Checker) dump(format string, args ...interface{}) { 66 fmt.Println(check.sprintf(format, args...)) 67 } 68 69 func (check *Checker) err(pos token.Pos, msg string, soft bool) { 70 // Cheap trick: Don't report errors with messages containing 71 // "invalid operand" or "invalid type" as those tend to be 72 // follow-on errors which don't add useful information. Only 73 // exclude them if these strings are not at the beginning, 74 // and only if we have at least one error already reported. 75 if check.firstErr != nil && (strings.Index(msg, "invalid operand") > 0 || strings.Index(msg, "invalid type") > 0) { 76 return 77 } 78 79 err := Error{check.fset, pos, msg, soft} 80 if check.firstErr == nil { 81 check.firstErr = err 82 } 83 84 f := check.conf.Error 85 if f == nil { 86 panic(bailout{}) // report only first error 87 } 88 f(err) 89 } 90 91 func (check *Checker) error(pos token.Pos, msg string) { 92 check.err(pos, msg, false) 93 } 94 95 func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) { 96 check.err(pos, check.sprintf(format, args...), false) 97 } 98 99 func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) { 100 check.err(pos, check.sprintf(format, args...), true) 101 } 102 103 func (check *Checker) invalidAST(pos token.Pos, format string, args ...interface{}) { 104 check.errorf(pos, "invalid AST: "+format, args...) 105 } 106 107 func (check *Checker) invalidArg(pos token.Pos, format string, args ...interface{}) { 108 check.errorf(pos, "invalid argument: "+format, args...) 109 } 110 111 func (check *Checker) invalidOp(pos token.Pos, format string, args ...interface{}) { 112 check.errorf(pos, "invalid operation: "+format, args...) 113 }