package  types 
 
import  ( 
	"bytes"  
	"fmt"  
	"go/ast"  
	"go/token"  
	"strconv"  
	"strings"  
) 
 
func  sprintf(fset  *token .FileSet , qf  Qualifier , tpSubscripts  bool , format  string , args  ...any ) string  { 
	for  i , arg  := range  args  { 
		switch  a := arg .(type ) { 
		case  nil : 
			arg  = "<nil>"  
		case  operand : 
			panic ("got operand instead of *operand" ) 
		case  *operand : 
			arg  = operandString (a , qf ) 
		case  token .Pos : 
			if  fset  != nil  { 
				arg  = fset .Position (a ).String () 
			} 
		case  ast .Expr : 
			arg  = ExprString (a ) 
		case  []ast .Expr : 
			var  buf  bytes .Buffer  
			buf .WriteByte ('[' ) 
			writeExprList (&buf , a ) 
			buf .WriteByte (']' ) 
			arg  = buf .String () 
		case  Object : 
			arg  = ObjectString (a , qf ) 
		case  Type : 
			var  buf  bytes .Buffer  
			w  := newTypeWriter (&buf , qf ) 
			w .tpSubscripts  = tpSubscripts  
			w .typ (a ) 
			arg  = buf .String () 
		case  []Type : 
			var  buf  bytes .Buffer  
			w  := newTypeWriter (&buf , qf ) 
			w .tpSubscripts  = tpSubscripts  
			buf .WriteByte ('[' ) 
			for  i , x  := range  a  { 
				if  i  > 0  { 
					buf .WriteString (", " ) 
				} 
				w .typ (x ) 
			} 
			buf .WriteByte (']' ) 
			arg  = buf .String () 
		case  []*TypeParam : 
			var  buf  bytes .Buffer  
			w  := newTypeWriter (&buf , qf ) 
			w .tpSubscripts  = tpSubscripts  
			buf .WriteByte ('[' ) 
			for  i , x  := range  a  { 
				if  i  > 0  { 
					buf .WriteString (", " ) 
				} 
				w .typ (x ) 
			} 
			buf .WriteByte (']' ) 
			arg  = buf .String () 
		} 
		args [i ] = arg  
	} 
	return  fmt .Sprintf (format , args ...) 
} 
 
 
func  (check  *Checker ) sprintf (format  string , args  ...any ) string  { 
	var  fset  *token .FileSet  
	var  qf  Qualifier  
	if  check  != nil  { 
		fset  = check .fset  
		qf  = check .qualifier  
	} 
	return  sprintf (fset , qf , false , format , args ...) 
} 
 
func  (check  *Checker ) trace (pos  token .Pos , format  string , args  ...any ) { 
	pos1  := check .fset .Position (pos ) 
	 
 
 
	w  := ndigits (pos1 .Line ) + ndigits (pos1 .Column ) 
	pad  := "     " [:max (5 -w , 0 )] 
	fmt .Printf ("%s%s:  %s%s\n" , 
		pos1 , 
		pad , 
		strings .Repeat (".  " , check .indent ), 
		sprintf (check .fset , check .qualifier , true , format , args ...), 
	) 
} 
 
 
 
 
func  ndigits(x  int ) int  { 
	switch  { 
	case  x  < 10 : 
		return  1  
	case  x  < 100 : 
		return  2  
	default : 
		return  3  
	} 
} 
 
 
func  (check  *Checker ) dump (format  string , args  ...any ) { 
	fmt .Println (sprintf (check .fset , check .qualifier , true , format , args ...)) 
} 
 
func  (check  *Checker ) qualifier (pkg  *Package ) string  { 
	 
	if  pkg  != check .pkg  { 
		if  check .pkgPathMap  == nil  { 
			check .pkgPathMap  = make (map [string ]map [string ]bool ) 
			check .seenPkgMap  = make (map [*Package ]bool ) 
			check .markImports (check .pkg ) 
		} 
		 
		if  len (check .pkgPathMap [pkg .name ]) > 1  { 
			return  strconv .Quote (pkg .path ) 
		} 
		return  pkg .name  
	} 
	return  ""  
} 
 
 
 
func  (check  *Checker ) markImports (pkg  *Package ) { 
	if  check .seenPkgMap [pkg ] { 
		return  
	} 
	check .seenPkgMap [pkg ] = true  
 
	forName , ok  := check .pkgPathMap [pkg .name ] 
	if  !ok  { 
		forName  = make (map [string ]bool ) 
		check .pkgPathMap [pkg .name ] = forName  
	} 
	forName [pkg .path ] = true  
 
	for  _ , imp  := range  pkg .imports  { 
		check .markImports (imp ) 
	} 
} 
 
 
func  stripAnnotations(s  string ) string  { 
	var  buf  strings .Builder  
	for  _ , r  := range  s  { 
		 
		if  r  < '₀'  || '₀' +10  <= r  {  
			buf .WriteRune (r ) 
		} 
	} 
	if  buf .Len () < len (s ) { 
		return  buf .String () 
	} 
	return  s  
} 
  
The pages are generated with Golds   v0.7.9-preview . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .