package emitimport ()typeallocatorstruct {usedmap[string]bool}// reservedIdents returns the identifiers a generated name must not collide with,// common to import-alias assignment and local-name allocation: the predeclared// universe, the destination package's own top-level names, and the lifted// type-parameter names. Keywords are not seeded here: go/token exposes no// enumerable keyword set, so they are rejected by the token.IsKeyword arm of each// collision predicate instead. Each caller augments the result with its own extra// category (set names for aliases, import aliases for locals).func ( *solve.DestInfo, map[string]bool) map[string]bool { := .ReservedNames()for := range { [] = true }return}func ( *solve.DestInfo, *qualifier, map[string]bool) *allocator { := reservedIdents(, )for , := range .aliasNames() { [] = true }return &allocator{used: }}// branch returns a sub-allocator that treats every name taken so far as// reserved but whose own allocations do not leak back to the parent. Names// allocated in one cleanup branch (an if-block or the cleanup closure) are// invisible to other branches, so each branch starts numbering afresh.func ( *allocator) () *allocator {return &allocator{used: maps.Clone(.used)}}func ( *allocator) ( string) string { = sanitizeIdent() := for := 2; .used[] || token.IsKeyword(); ++ { = + strconv.Itoa() } .used[] = truereturn}func ( string) string {// A keyword base (a type named Type lowers to "type") is a valid identifier // shape; let it through so the allocator, whose collision test rejects every // keyword, suffixes it to a readable "type2" rather than collapsing it to "v".if == "" || == "_" || (!token.IsIdentifier() && !token.IsKeyword()) {return"v" }return}// baseName derives a readable local-variable base name from a type.func ( types.Type) string {switch u := .(type) {case *types.Pointer:return (.Elem())case *types.Slice:return (.Elem()) + "s"case *types.Array:return (.Elem()) + "s"case *types.Named:returnlowerCamel(.Obj().Name())case *types.Alias:returnlowerCamel(.Obj().Name())case *types.Basic:returnlowerCamel(.Name())case *types.Map:return"m"case *types.Chan:return"ch"case *types.Interface:return"iface"case *types.Signature:return"fn"case *types.TypeParam:returnlowerCamel(.Obj().Name()) }return"v"}// cleanupBaseName derives a cleanup local's base name from the provider function// that returns it, e.g. OpenConn's teardown becomes openConnCleanup. A cleanup// result only ever comes from a function or method provider, so its Fn is always// set. Naming after the provider (not the value the provider yields) keeps the// cleanup unambiguous even when a provider returns several values.func ( *types.Func) string {returnlowerCamel(.Name()) + "Cleanup"}// commonInitialisms are acronyms treated as one unit when lowering an// identifier's first word. This keeps the camelCase boundary after the whole// acronym (HTTPServer becomes httpServer) and stops a leading acronym from// merging with the next one (XMLHTTPRequest becomes xmlHTTPRequest).varcommonInitialisms = map[string]bool{"ACL": true, "API": true, "ASCII": true, "CPU": true, "CSS": true,"DNS": true, "EOF": true, "GUID": true, "HTML": true, "HTTP": true,"HTTPS": true, "ID": true, "IP": true, "JSON": true, "LHS": true,"QPS": true, "RAM": true, "RHS": true, "RPC": true, "SLA": true,"SMTP": true, "SQL": true, "SSH": true, "TCP": true, "TLS": true,"TTL": true, "UDP": true, "UI": true, "UID": true, "UUID": true,"URI": true, "URL": true, "UTF8": true, "VM": true, "XML": true,"XMPP": true, "XSRF": true, "XSS": true,}// lowerCamel lowercases the first word of an identifier while preserving// camelCase: User → user, DB → db, DB2 → db2, HTTPServer → httpServer,// XMLHTTPRequest → xmlHTTPRequest. A leading common initialism is lowered as a// unit. Otherwise the leading run of capitals is lowered, except for its final// capital when a lowercase letter follows it, since that capital begins the next// word.func ( string) string { := firstWordLen()returnstrings.ToLower([:]) + [:]}// firstWordLen returns the byte length of the prefix lowerCamel lowercases,// which is the identifier's first word. A leading common initialism is the whole// word. Otherwise the word is the leading run of capitals, dropping its final// capital when a lowercase letter follows, since that capital starts the next word.func ( string) int {if := leadingInitialism(); != "" {returnlen() } , := 0, 0for , := range {if !unicode.IsUpper() {if > 1 && unicode.IsLower() {return// the run's final capital begins the next word }return } ++ = }returnlen() // all of s is a single run of capitals}// leadingInitialism returns the longest common initialism that prefixes s at a// word boundary, or "". A word boundary means the initialism is all of s, or the// rune right after it is uppercase.func ( string) string { := ""for := rangecommonInitialisms {iflen() <= len() || !strings.HasPrefix(, ) {continue }if := [len():]; == "" || startsUpper() { = } }return}func ( string) bool { , := utf8.DecodeRuneInString()returnunicode.IsUpper()}
The pages are generated with Goldsv0.8.4. (GOOS=linux GOARCH=amd64)