Source file src/go/types/errors.go

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

View as plain text