Black Lives Matter. Support the Equal Justice Initiative.

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  	"strconv"
    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  	// Qualify the package unless it's the package being type-checked.
    29  	if pkg != check.pkg {
    30  		// If the same package name was used by multiple packages, display the full path.
    31  		if check.pkgCnt[pkg.name] > 1 {
    32  			return strconv.Quote(pkg.path)
    33  		}
    34  		return pkg.name
    35  	}
    36  	return ""
    37  }
    38  
    39  func (check *Checker) sprintf(format string, args ...interface{}) string {
    40  	for i, arg := range args {
    41  		switch a := arg.(type) {
    42  		case nil:
    43  			arg = "<nil>"
    44  		case operand:
    45  			panic("internal error: should always pass *operand")
    46  		case *operand:
    47  			arg = operandString(a, check.qualifier)
    48  		case token.Pos:
    49  			arg = check.fset.Position(a).String()
    50  		case ast.Expr:
    51  			arg = ExprString(a)
    52  		case Object:
    53  			arg = ObjectString(a, check.qualifier)
    54  		case Type:
    55  			arg = TypeString(a, check.qualifier)
    56  		}
    57  		args[i] = arg
    58  	}
    59  	return fmt.Sprintf(format, args...)
    60  }
    61  
    62  func (check *Checker) trace(pos token.Pos, format string, args ...interface{}) {
    63  	fmt.Printf("%s:\t%s%s\n",
    64  		check.fset.Position(pos),
    65  		strings.Repeat(".  ", check.indent),
    66  		check.sprintf(format, args...),
    67  	)
    68  }
    69  
    70  // dump is only needed for debugging
    71  func (check *Checker) dump(format string, args ...interface{}) {
    72  	fmt.Println(check.sprintf(format, args...))
    73  }
    74  
    75  func (check *Checker) err(pos token.Pos, msg string, soft bool) {
    76  	// Cheap trick: Don't report errors with messages containing
    77  	// "invalid operand" or "invalid type" as those tend to be
    78  	// follow-on errors which don't add useful information. Only
    79  	// exclude them if these strings are not at the beginning,
    80  	// and only if we have at least one error already reported.
    81  	if check.firstErr != nil && (strings.Index(msg, "invalid operand") > 0 || strings.Index(msg, "invalid type") > 0) {
    82  		return
    83  	}
    84  
    85  	err := Error{check.fset, pos, msg, soft}
    86  	if check.firstErr == nil {
    87  		check.firstErr = err
    88  	}
    89  
    90  	if trace {
    91  		check.trace(pos, "ERROR: %s", msg)
    92  	}
    93  
    94  	f := check.conf.Error
    95  	if f == nil {
    96  		panic(bailout{}) // report only first error
    97  	}
    98  	f(err)
    99  }
   100  
   101  func (check *Checker) error(pos token.Pos, msg string) {
   102  	check.err(pos, msg, false)
   103  }
   104  
   105  func (check *Checker) errorf(pos token.Pos, format string, args ...interface{}) {
   106  	check.err(pos, check.sprintf(format, args...), false)
   107  }
   108  
   109  func (check *Checker) softErrorf(pos token.Pos, format string, args ...interface{}) {
   110  	check.err(pos, check.sprintf(format, args...), true)
   111  }
   112  
   113  func (check *Checker) invalidAST(pos token.Pos, format string, args ...interface{}) {
   114  	check.errorf(pos, "invalid AST: "+format, args...)
   115  }
   116  
   117  func (check *Checker) invalidArg(pos token.Pos, format string, args ...interface{}) {
   118  	check.errorf(pos, "invalid argument: "+format, args...)
   119  }
   120  
   121  func (check *Checker) invalidOp(pos token.Pos, format string, args ...interface{}) {
   122  	check.errorf(pos, "invalid operation: "+format, args...)
   123  }
   124  

View as plain text