// Code generated by "go test -run=Generate -write=all"; DO NOT EDIT.// Source: ../../cmd/compile/internal/types2/typestring.go// Copyright 2013 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.// This file implements printing of types.package typesimport ()// A Qualifier controls how named package-level objects are printed in// calls to [TypeString], [ObjectString], and [SelectionString].//// These three formatting routines call the Qualifier for each// package-level object O, and if the Qualifier returns a non-empty// string p, the object is printed in the form p.O.// If it returns an empty string, only the object name O is printed.//// Using a nil Qualifier is equivalent to using (*[Package]).Path: the// object is qualified by the import path, e.g., "encoding/json.Marshal".typeQualifierfunc(*Package) string// RelativeTo returns a [Qualifier] that fully qualifies members of// all packages other than pkg.func ( *Package) Qualifier {if == nil {returnnil }returnfunc( *Package) string {if == {return""// same package; unqualified }return .Path() }}// TypeString returns the string representation of typ.// The [Qualifier] controls the printing of// package-level objects, and may be nil.func ( Type, Qualifier) string {varbytes.BufferWriteType(&, , )return .String()}// WriteType writes the string representation of typ to buf.// The [Qualifier] controls the printing of// package-level objects, and may be nil.func ( *bytes.Buffer, Type, Qualifier) {newTypeWriter(, ).typ()}// WriteSignature writes the representation of the signature sig to buf,// without a leading "func" keyword. The [Qualifier] controls the printing// of package-level objects, and may be nil.func ( *bytes.Buffer, *Signature, Qualifier) {newTypeWriter(, ).signature()}type typeWriter struct { buf *bytes.Buffer seen map[Type]bool qf Qualifier ctxt *Context// if non-nil, we are type hashing tparams *TypeParamList// local type parameters paramNames bool// if set, write function parameter names, otherwise, write types only tpSubscripts bool// if set, write type parameter indices as subscripts pkgInfo bool// package-annotate first unexported-type field to avoid confusing type description}func newTypeWriter( *bytes.Buffer, Qualifier) *typeWriter {return &typeWriter{, make(map[Type]bool), , nil, nil, true, false, false}}func newTypeHasher( *bytes.Buffer, *Context) *typeWriter {assert( != nil)return &typeWriter{, make(map[Type]bool), nil, , nil, false, false, false}}func ( *typeWriter) ( byte) {if .ctxt != nil {if == ' ' { = '#' } .buf.WriteByte()return } .buf.WriteByte()if == ',' || == ';' { .buf.WriteByte(' ') }}func ( *typeWriter) ( string) { .buf.WriteString()}func ( *typeWriter) ( string) {if .ctxt != nil {panic() } .buf.WriteString("<" + + ">")}func ( *typeWriter) ( Type) {if .seen[] { .error("cycle to " + goTypeName())return } .seen[] = truedeferdelete(.seen, )switch t := .(type) {casenil: .error("nil")case *Basic:// exported basic types go into package unsafe // (currently this is just unsafe.Pointer)ifisExported(.name) {if , := Unsafe.scope.Lookup(.name).(*TypeName); != nil { .typeName()break } } .string(.name)case *Array: .byte('[') .string(strconv.FormatInt(.len, 10)) .byte(']') .(.elem)case *Slice: .string("[]") .(.elem)case *Struct: .string("struct{")for , := range .fields {if > 0 { .byte(';') }// If disambiguating one struct for another, look for the first unexported field. // Do this first in case of nested structs; tag the first-outermost field. := falseif .qf == nil && .pkgInfo && !isExported(.name) {// note for embedded types, type name is field name, and "string" etc are lower case hence unexported. = true .pkgInfo = false// only tag once }// This doesn't do the right thing for embedded type // aliases where we should print the alias name, not // the aliased type (see go.dev/issue/44410).if !.embedded { .string(.name) .byte(' ') } .(.typ)if { .string(" /* package ") .string(.pkg.Path()) .string(" */ ") }if := .Tag(); != "" { .byte(' ')// TODO(gri) If tag contains blanks, replacing them with '#' // in Context.TypeHash may produce another tag // accidentally. .string(strconv.Quote()) } } .byte('}')case *Pointer: .byte('*') .(.base)case *Tuple: .tuple(, false)case *Signature: .string("func") .signature()case *Union:// Unions only appear as (syntactic) embedded elements // in interfaces and syntactically cannot be empty.if .Len() == 0 { .error("empty union")break }for , := range .terms {if > 0 { .string(termSep) }if .tilde { .byte('~') } .(.typ) }case *Interface:if .ctxt == nil {if == universeAnyAlias.Type().Underlying() {// When not hashing, we can try to improve type strings by writing "any" // for a type that is pointer-identical to universeAny. // TODO(rfindley): this logic should not be necessary with // gotypesalias=1. Remove once that is always the case. .string("any")break }if == asNamed(universeComparable.Type()).underlying { .string("interface{comparable}")break } }if .implicit {iflen(.methods) == 0 && len(.embeddeds) == 1 { .(.embeddeds[0])break }// Something's wrong with the implicit interface. // Print it as such and continue. .string("/* implicit */ ") } .string("interface{") := trueif .ctxt != nil { .typeSet(.typeSet()) } else {for , := range .methods {if ! { .byte(';') } = false .string(.name) .signature(.typ.(*Signature)) }for , := range .embeddeds {if ! { .byte(';') } = false .() } } .byte('}')case *Map: .string("map[") .(.key) .byte(']') .(.elem)case *Chan:varstringvarboolswitch .dir {caseSendRecv: = "chan "// chan (<-chan T) requires parenthesesif , := .elem.(*Chan); != nil && .dir == RecvOnly { = true }caseSendOnly: = "chan<- "caseRecvOnly: = "<-chan "default: .error("unknown channel direction") } .string()if { .byte('(') } .(.elem)if { .byte(')') }case *Named:// If hashing, write a unique prefix for t to represent its identity, since // named type identity is pointer identity.if .ctxt != nil { .string(strconv.Itoa(.ctxt.getID())) } .typeName(.obj) // when hashing written for readability of the hash onlyif .inst != nil {// instantiated type .typeList(.inst.targs.list()) } elseif .ctxt == nil && .TypeParams().Len() != 0 { // For type hashing, don't need to format the TypeParams// parameterized type .tParamList(.TypeParams().list()) }case *TypeParam:if .obj == nil { .error("unnamed type parameter")break }if := tparamIndex(.tparams.list(), ); >= 0 {// The names of type parameters that are declared by the type being // hashed are not part of the type identity. Replace them with a // placeholder indicating their index. .string(fmt.Sprintf("$%d", )) } else { .string(.obj.name)if .tpSubscripts || .ctxt != nil { .string(subscript(.id)) }// If the type parameter name is the same as a predeclared object // (say int), point out where it is declared to avoid confusing // error messages. This doesn't need to be super-elegant; we just // need a clear indication that this is not a predeclared name.if .ctxt == nil && Universe.Lookup(.obj.name) != nil {ifisTypes2 { .string(fmt.Sprintf(" /* with %s declared at %v */", .obj.name, .obj.Pos())) } else {// Can't print position information because // we don't have a token.FileSet accessible. .string("/* type parameter */") } } }case *Alias: .typeName(.obj)if := .targs.list(); len() != 0 {// instantiated type .typeList() }if .ctxt != nil {// TODO(gri) do we need to print the alias type name, too? .(Unalias(.obj.typ)) }default:// For externally defined implementations of Type. // Note: In this case cycles won't be caught. .string(.String()) }}// typeSet writes a canonical hash for an interface type set.func ( *typeWriter) ( *_TypeSet) {assert(.ctxt != nil) := truefor , := range .methods {if ! { .byte(';') } = false .string(.name) .signature(.typ.(*Signature)) }switch {case .terms.isAll():// nothing to docase .terms.isEmpty(): .string(.terms.String())default:var []stringfor , := range .terms {// terms are not canonically sorted, so we sort their hashes instead.varbytes.Bufferif .tilde { .WriteByte('~') }newTypeHasher(&, .ctxt).typ(.typ) = append(, .String()) }sort.Strings()if ! { .byte(';') } .string(strings.Join(, "|")) }}func ( *typeWriter) ( []Type) { .byte('[')for , := range {if > 0 { .byte(',') } .typ() } .byte(']')}func ( *typeWriter) ( []*TypeParam) { .byte('[')varTypefor , := range {// Determine the type parameter and its constraint. // list is expected to hold type parameter names, // but don't crash if that's not the case.if == nil { .error("nil type parameter")continue }if > 0 {if .bound != {// bound changed - write previous one before advancing .byte(' ') .typ() } .byte(',') } = .bound .typ() }if != nil { .byte(' ') .typ() } .byte(']')}func ( *typeWriter) ( *TypeName) { .string(packagePrefix(.pkg, .qf)) .string(.name)}func ( *typeWriter) ( *Tuple, bool) { .byte('(')if != nil {for , := range .vars {if > 0 { .byte(',') }// parameter names are ignored for type identity and thus type hashesif .ctxt == nil && .name != "" && .paramNames { .string(.name) .byte(' ') } := .typif && == len(.vars)-1 {if , := .(*Slice); { .string("...") = .elem } else {// special case: // append(s, "foo"...) leads to signature func([]byte, string...)if , := under().(*Basic); == nil || .kind != String { .error("expected string type")continue } .typ() .string("...")continue } } .typ() } } .byte(')')}func ( *typeWriter) ( *Signature) {if .TypeParams().Len() != 0 {if .ctxt != nil {assert(.tparams == nil) .tparams = .TypeParams()deferfunc() { .tparams = nil }() } .tParamList(.TypeParams().list()) } .tuple(.params, .variadic) := .results.Len()if == 0 {// no resultreturn } .byte(' ')if == 1 && (.ctxt != nil || .results.vars[0].name == "") {// single unnamed result (if type hashing, name must be ignored) .typ(.results.vars[0].typ)return }// multiple or named result(s) .tuple(.results, false)}// subscript returns the decimal (utf8) representation of x using subscript digits.func subscript( uint64) string {const = len("₀") // all digits 0...9 have the same utf8 widthvar [32 * ]byte := len()for { -= utf8.EncodeRune([:], '₀'+rune(%10)) // '₀' == U+2080 /= 10if == 0 {break } }returnstring([:])}
The pages are generated with Goldsv0.7.0-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.