Home | History | Annotate | Download | only in types
      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 	err := Error{check.fset, pos, msg, soft}
     71 	if check.firstErr == nil {
     72 		check.firstErr = err
     73 	}
     74 	f := check.conf.Error
     75 	if f == nil {
     76 		panic(bailout{}) // report only first error
     77 	}
     78 	f(err)
     79 }
     80 
     81 func (check *Checker) error(pos token.Pos, msg string) {
     82 	check.err(pos, msg, false)
     83 }
     84 
     85 func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) {
     86 	check.err(pos, check.sprintf(format, args...), false)
     87 }
     88 
     89 func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) {
     90 	check.err(pos, check.sprintf(format, args...), true)
     91 }
     92 
     93 func (check *Checker) invalidAST(pos token.Pos, format string, args ...interface{}) {
     94 	check.errorf(pos, "invalid AST: "+format, args...)
     95 }
     96 
     97 func (check *Checker) invalidArg(pos token.Pos, format string, args ...interface{}) {
     98 	check.errorf(pos, "invalid argument: "+format, args...)
     99 }
    100 
    101 func (check *Checker) invalidOp(pos token.Pos, format string, args ...interface{}) {
    102 	check.errorf(pos, "invalid operation: "+format, args...)
    103 }
    104