├── .gitignore ├── .travis.yml ├── LICENSE ├── Readme.md ├── cmd ├── fillstruct │ ├── Readme.md │ ├── fill.go │ ├── fill_test.go │ ├── main.go │ └── typestring.go ├── fillswitch │ ├── Readme.md │ ├── fill.go │ ├── fill_test.go │ ├── main.go │ ├── testdata │ │ ├── broken_typeswitch │ │ │ ├── input.go │ │ │ └── output.golden │ │ ├── empty_switch │ │ │ ├── input.go │ │ │ └── output.golden │ │ ├── multipkgs │ │ │ ├── input.go │ │ │ ├── input_test.go │ │ │ └── output.golden │ │ ├── switch_1 │ │ │ ├── input.go │ │ │ └── output.golden │ │ ├── typeswitch_1 │ │ │ ├── input.go │ │ │ └── output.golden │ │ ├── typeswitch_2 │ │ │ ├── input.go │ │ │ └── output.golden │ │ ├── typeswitch_3 │ │ │ ├── input.go │ │ │ └── output.golden │ │ ├── typeswitch_4 │ │ │ ├── input.go │ │ │ └── output.golden │ │ └── typeswitch_5 │ │ │ ├── input.go │ │ │ ├── internal │ │ │ └── foo │ │ │ │ └── foo.go │ │ │ └── output.golden │ └── typestring.go └── fixplurals │ ├── Readme.md │ └── main.go ├── go.mod ├── go.sum └── vendor ├── github.com └── kisielk │ └── gotool │ ├── .travis.yml │ ├── LEGAL │ ├── LICENSE │ ├── README.md │ ├── go13.go │ ├── go14-15.go │ ├── go16-18.go │ ├── internal │ └── load │ │ ├── path.go │ │ ├── pkg.go │ │ └── search.go │ ├── match.go │ ├── match18.go │ └── tool.go ├── golang.org └── x │ ├── mod │ ├── LICENSE │ ├── PATENTS │ └── semver │ │ └── semver.go │ └── tools │ ├── LICENSE │ ├── PATENTS │ ├── go │ ├── ast │ │ └── astutil │ │ │ ├── enclosing.go │ │ │ ├── imports.go │ │ │ ├── rewrite.go │ │ │ └── util.go │ ├── buildutil │ │ ├── allpackages.go │ │ ├── fakecontext.go │ │ ├── overlay.go │ │ ├── tags.go │ │ └── util.go │ ├── gcexportdata │ │ ├── gcexportdata.go │ │ └── importer.go │ ├── internal │ │ ├── cgo │ │ │ ├── cgo.go │ │ │ └── cgo_pkgconfig.go │ │ └── packagesdriver │ │ │ └── sizes.go │ ├── loader │ │ ├── doc.go │ │ ├── loader.go │ │ └── util.go │ ├── packages │ │ ├── doc.go │ │ ├── external.go │ │ ├── golist.go │ │ ├── golist_overlay.go │ │ ├── loadmode_string.go │ │ ├── packages.go │ │ └── visit.go │ └── types │ │ └── objectpath │ │ └── objectpath.go │ ├── internal │ ├── event │ │ ├── core │ │ │ ├── event.go │ │ │ ├── export.go │ │ │ └── fast.go │ │ ├── doc.go │ │ ├── event.go │ │ ├── keys │ │ │ ├── keys.go │ │ │ ├── standard.go │ │ │ └── util.go │ │ ├── label │ │ │ └── label.go │ │ └── tag │ │ │ └── tag.go │ ├── gcimporter │ │ ├── bimport.go │ │ ├── exportdata.go │ │ ├── gcimporter.go │ │ ├── iexport.go │ │ ├── iimport.go │ │ ├── newInterface10.go │ │ ├── newInterface11.go │ │ ├── support_go117.go │ │ ├── support_go118.go │ │ ├── unified_no.go │ │ ├── unified_yes.go │ │ ├── ureader_no.go │ │ └── ureader_yes.go │ ├── gocommand │ │ ├── invoke.go │ │ ├── vendor.go │ │ └── version.go │ ├── packagesinternal │ │ └── packages.go │ ├── pkgbits │ │ ├── codes.go │ │ ├── decoder.go │ │ ├── doc.go │ │ ├── encoder.go │ │ ├── flags.go │ │ ├── frames_go1.go │ │ ├── frames_go17.go │ │ ├── reloc.go │ │ ├── support.go │ │ ├── sync.go │ │ └── syncmarker_string.go │ ├── tokeninternal │ │ └── tokeninternal.go │ ├── typeparams │ │ ├── common.go │ │ ├── coretype.go │ │ ├── normalize.go │ │ ├── termlist.go │ │ └── typeterm.go │ ├── typesinternal │ │ ├── errorcode.go │ │ ├── errorcode_string.go │ │ ├── types.go │ │ └── types_118.go │ └── versions │ │ ├── gover.go │ │ ├── types.go │ │ ├── types_go121.go │ │ ├── types_go122.go │ │ └── versions.go │ └── refactor │ └── importgraph │ └── graph.go └── modules.txt /.gitignore: -------------------------------------------------------------------------------- 1 | coverage.out 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.12.x 5 | - 1.13.x 6 | - tip 7 | 8 | git: 9 | depth: 1 10 | 11 | os: 12 | - linux 13 | - osx 14 | 15 | notifications: 16 | email: 17 | on_success: change 18 | on_failure: always 19 | 20 | before_install: 21 | - go get github.com/mattn/goveralls 22 | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.21.0 23 | 24 | install: true 25 | 26 | script: 27 | - golangci-lint run --enable-all -D funlen,gocognit,gocyclo,godox,lll,scopelint,wsl 28 | - go test -race -v -covermode=atomic -coverprofile=coverage.out ./... 29 | - goveralls -coverprofile=coverage.out -service=travis-ci 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 David R. Jenni. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # reftools [![Build Status](https://travis-ci.org/davidrjenni/reftools.svg?branch=master)](https://travis-ci.org/davidrjenni/reftools) [![Coverage Status](https://coveralls.io/repos/github/davidrjenni/reftools/badge.svg)](https://coveralls.io/github/davidrjenni/reftools) [![GoDoc](https://godoc.org/github.com/davidrjenni/reftools?status.svg)](https://godoc.org/github.com/davidrjenni/reftools) [![Go Report Card](https://goreportcard.com/badge/github.com/davidrjenni/reftools)](https://goreportcard.com/report/github.com/davidrjenni/reftools) 2 | 3 | reftools - refactoring tools for Go 4 | 5 | --- 6 | 7 | ## Tools 8 | 9 | | Tool | Description | 10 | |-------------------------------|----------------------------------------------------------------------| 11 | | [fixplurals](cmd/fixplurals/) | remove redundant parameter and result types from function signatures | 12 | | [fillstruct](cmd/fillstruct/) | fills a struct literal with default values | 13 | | [fillswitch](cmd/fillswitch/) | fills a (type) switch statement with case statements | 14 | -------------------------------------------------------------------------------- /cmd/fillstruct/Readme.md: -------------------------------------------------------------------------------- 1 | # fillstruct [![Build Status](https://travis-ci.org/davidrjenni/reftools.svg?branch=master)](https://travis-ci.org/davidrjenni/reftools) [![Coverage Status](https://coveralls.io/repos/github/davidrjenni/reftools/badge.svg)](https://coveralls.io/github/davidrjenni/reftools) [![GoDoc](https://godoc.org/github.com/davidrjenni/reftools?status.svg)](https://godoc.org/github.com/davidrjenni/reftools/cmd/fillstruct) [![Go Report Card](https://goreportcard.com/badge/github.com/davidrjenni/reftools)](https://goreportcard.com/report/github.com/davidrjenni/reftools) 2 | 3 | fillstruct - fills a struct literal with default values 4 | 5 | --- 6 | 7 | For example, given the following types, 8 | ``` 9 | type User struct { 10 | ID int64 11 | Name string 12 | Addr *Address 13 | } 14 | 15 | type Address struct { 16 | City string 17 | ZIP int 18 | LatLng [2]float64 19 | } 20 | ``` 21 | the following struct literal 22 | ``` 23 | var frank = User{} 24 | ``` 25 | becomes: 26 | ``` 27 | var frank = User{ 28 | ID: 0, 29 | Name: "", 30 | Addr: &Address{ 31 | City: "", 32 | ZIP: 0, 33 | LatLng: [2]float64{ 34 | 0.0, 35 | 0.0, 36 | }, 37 | }, 38 | } 39 | ``` 40 | after applying fillstruct. 41 | 42 | ## Installation 43 | 44 | ``` 45 | % go get -u github.com/davidrjenni/reftools/cmd/fillstruct 46 | ``` 47 | 48 | ## Usage 49 | 50 | ``` 51 | % fillstruct [-modified] -file= -offset= -line= 52 | ``` 53 | 54 | Flags: 55 | 56 | -file: filename 57 | -modified: read an archive of modified files from stdin 58 | -offset: byte offset of the struct literal, optional if -line is present 59 | -line: line number of the struct literal, optional if -offset is present 60 | 61 | If -offset as well as -line are present, then the tool first uses the 62 | more specific offset information. If there was no struct literal found 63 | at the given offset, then the line information is used. 64 | -------------------------------------------------------------------------------- /cmd/fillstruct/typestring.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 David R. Jenni. 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 | // Plundered from go/types; customized. 6 | 7 | // Copyright (c) 2009 The Go Authors. All rights reserved. 8 | // 9 | // Redistribution and use in source and binary forms, with or without 10 | // modification, are permitted provided that the following conditions are 11 | // met: 12 | // 13 | // * Redistributions of source code must retain the above copyright 14 | // notice, this list of conditions and the following disclaimer. 15 | // * Redistributions in binary form must reproduce the above 16 | // copyright notice, this list of conditions and the following disclaimer 17 | // in the documentation and/or other materials provided with the 18 | // distribution. 19 | // * Neither the name of Google Inc. nor the names of its 20 | // contributors may be used to endorse or promote products derived from 21 | // this software without specific prior written permission. 22 | // 23 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | // This file implements printing of types. 36 | 37 | package main 38 | 39 | import ( 40 | "bytes" 41 | "fmt" 42 | "go/types" 43 | ) 44 | 45 | type typeWriter struct { 46 | buf *bytes.Buffer 47 | pkg *types.Package 48 | hasError bool 49 | importNames map[string]string 50 | } 51 | 52 | func typeString(pkg *types.Package, importNames map[string]string, typ types.Type) (string, bool) { 53 | w := typeWriter{ 54 | buf: &bytes.Buffer{}, 55 | pkg: pkg, 56 | importNames: importNames, 57 | } 58 | w.writeType(typ, make([]types.Type, 0, 8)) 59 | return w.buf.String(), !w.hasError 60 | } 61 | 62 | func (w *typeWriter) writeType(typ types.Type, visited []types.Type) { 63 | // Theoretically, this is a quadratic lookup algorithm, but in 64 | // practice deeply nested composite types with unnamed component 65 | // types are uncommon. This code is likely more efficient than 66 | // using a map. 67 | for _, t := range visited { 68 | if t == typ { 69 | fmt.Fprintf(w.buf, "○%T", typ) // cycle to typ 70 | return 71 | } 72 | } 73 | visited = append(visited, typ) 74 | 75 | switch t := typ.(type) { 76 | case nil: 77 | w.buf.WriteString("nil") 78 | 79 | case *types.Basic: 80 | switch t.Kind() { 81 | case types.Invalid: 82 | w.hasError = true 83 | case types.UnsafePointer: 84 | w.buf.WriteString("unsafe.") 85 | } 86 | w.buf.WriteString(t.Name()) 87 | 88 | case *types.Array: 89 | fmt.Fprintf(w.buf, "[%d]", t.Len()) 90 | w.writeType(t.Elem(), visited) 91 | 92 | case *types.Slice: 93 | w.buf.WriteString("[]") 94 | w.writeType(t.Elem(), visited) 95 | 96 | case *types.Struct: 97 | w.buf.WriteString("struct{") 98 | for i := 0; i < t.NumFields(); i++ { 99 | f := t.Field(i) 100 | if i > 0 { 101 | w.buf.WriteString("; ") 102 | } 103 | if !f.Anonymous() { 104 | w.buf.WriteString(f.Name()) 105 | w.buf.WriteByte(' ') 106 | } 107 | w.writeType(f.Type(), visited) 108 | if tag := t.Tag(i); tag != "" { 109 | fmt.Fprintf(w.buf, " %q", tag) 110 | } 111 | } 112 | w.buf.WriteByte('}') 113 | 114 | case *types.Pointer: 115 | w.buf.WriteByte('*') 116 | w.writeType(t.Elem(), visited) 117 | 118 | case *types.Tuple: 119 | w.writeTuple(t, false, visited) 120 | 121 | case *types.Signature: 122 | w.buf.WriteString("func") 123 | w.writeSignature(t, visited) 124 | 125 | case *types.Interface: 126 | // We write the source-level methods and embedded types rather 127 | // than the actual method set since resolved method signatures 128 | // may have non-printable cycles if parameters have anonymous 129 | // interface types that (directly or indirectly) embed the 130 | // current interface. For instance, consider the result type 131 | // of m: 132 | // 133 | // type T interface{ 134 | // m() interface{ T } 135 | // } 136 | // 137 | w.buf.WriteString("interface{") 138 | // print explicit interface methods and embedded types 139 | for i := 0; i < t.NumMethods(); i++ { 140 | m := t.Method(i) 141 | if i > 0 { 142 | w.buf.WriteString("; ") 143 | } 144 | w.buf.WriteString(m.Name()) 145 | w.writeSignature(m.Type().(*types.Signature), visited) 146 | } 147 | for i := 0; i < t.NumEmbeddeds(); i++ { 148 | if i > 0 || t.NumMethods() > 0 { 149 | w.buf.WriteString("; ") 150 | } 151 | w.writeType(t.EmbeddedType(i), visited) 152 | } 153 | w.buf.WriteByte('}') 154 | 155 | case *types.Map: 156 | w.buf.WriteString("map[") 157 | w.writeType(t.Key(), visited) 158 | w.buf.WriteByte(']') 159 | w.writeType(t.Elem(), visited) 160 | 161 | case *types.Chan: 162 | var s string 163 | var parens bool 164 | switch t.Dir() { 165 | case types.SendRecv: 166 | s = "chan " 167 | // chan (<-chan T) requires parentheses 168 | if c, _ := t.Elem().(*types.Chan); c != nil && c.Dir() == types.RecvOnly { 169 | parens = true 170 | } 171 | case types.SendOnly: 172 | s = "chan<- " 173 | case types.RecvOnly: 174 | s = "<-chan " 175 | default: 176 | panic("unreachable") 177 | } 178 | w.buf.WriteString(s) 179 | if parens { 180 | w.buf.WriteByte('(') 181 | } 182 | w.writeType(t.Elem(), visited) 183 | if parens { 184 | w.buf.WriteByte(')') 185 | } 186 | 187 | case *types.Named: 188 | if isImported(w.pkg, t) && t.Obj().Pkg() != nil { 189 | pkg := t.Obj().Pkg() 190 | if name, ok := w.importNames[pkg.Path()]; ok { 191 | if name == "." { 192 | w.buf.WriteString(t.Obj().Name()) 193 | } else { 194 | w.buf.WriteString(fmt.Sprintf("%s.%s", name, t.Obj().Name())) 195 | } 196 | } else { 197 | w.buf.WriteString(fmt.Sprintf("%s.%s", pkg.Name(), t.Obj().Name())) 198 | } 199 | } else { 200 | w.buf.WriteString(t.Obj().Name()) 201 | } 202 | 203 | default: 204 | // For externally defined implementations of Type. 205 | w.buf.WriteString(t.String()) 206 | } 207 | } 208 | 209 | func (w *typeWriter) writeTuple(tup *types.Tuple, variadic bool, visited []types.Type) { 210 | w.buf.WriteByte('(') 211 | if tup != nil { 212 | for i := 0; i < tup.Len(); i++ { 213 | v := tup.At(i) 214 | if i > 0 { 215 | w.buf.WriteString(", ") 216 | } 217 | if v.Name() != "" { 218 | w.buf.WriteString(v.Name()) 219 | w.buf.WriteByte(' ') 220 | } 221 | typ := v.Type() 222 | if variadic && i == tup.Len()-1 { 223 | if s, ok := typ.(*types.Slice); ok { 224 | w.buf.WriteString("...") 225 | typ = s.Elem() 226 | } else { 227 | // special case: 228 | // append(s, "foo"...) leads to signature func([]byte, string...) 229 | if t, ok := typ.Underlying().(*types.Basic); !ok || t.Kind() != types.String { 230 | panic("internal error: string type expected") 231 | } 232 | w.writeType(typ, visited) 233 | w.buf.WriteString("...") 234 | continue 235 | } 236 | } 237 | w.writeType(typ, visited) 238 | } 239 | } 240 | w.buf.WriteByte(')') 241 | } 242 | 243 | func (w *typeWriter) writeSignature(sig *types.Signature, visited []types.Type) { 244 | w.writeTuple(sig.Params(), sig.Variadic(), visited) 245 | 246 | n := sig.Results().Len() 247 | if n == 0 { 248 | return // no result 249 | } 250 | 251 | w.buf.WriteByte(' ') 252 | if n == 1 && sig.Results().At(0).Name() == "" { 253 | // single unnamed result 254 | w.writeType(sig.Results().At(0).Type(), visited) 255 | return 256 | } 257 | 258 | // multiple or named result(s) 259 | w.writeTuple(sig.Results(), false, visited) 260 | } 261 | -------------------------------------------------------------------------------- /cmd/fillswitch/Readme.md: -------------------------------------------------------------------------------- 1 | # fillswitch [![Build Status](https://travis-ci.org/davidrjenni/reftools.svg?branch=master)](https://travis-ci.org/davidrjenni/reftools) [![Coverage Status](https://coveralls.io/repos/github/davidrjenni/reftools/badge.svg)](https://coveralls.io/github/davidrjenni/reftools) [![GoDoc](https://godoc.org/github.com/davidrjenni/reftools?status.svg)](https://godoc.org/github.com/davidrjenni/reftools/cmd/fillswitch) [![Go Report Card](https://goreportcard.com/badge/github.com/davidrjenni/reftools)](https://goreportcard.com/report/github.com/davidrjenni/reftools) 2 | 3 | fillswitch - fills (type) switches with case statements 4 | 5 | --- 6 | 7 | For example, the following (type) switches, 8 | ``` 9 | var stmt ast.Stmt 10 | switch stmt := stmt.(type) { 11 | } 12 | 13 | var kind ast.ObjKind 14 | switch kind { 15 | } 16 | ``` 17 | become: 18 | ``` 19 | var stmt ast.Stmt 20 | switch stmt := stmt.(type) { 21 | case *ast.AssignStmt: 22 | case *ast.BadStmt: 23 | case *ast.BlockStmt: 24 | case *ast.BranchStmt: 25 | case *ast.CaseClause: 26 | case *ast.CommClause: 27 | case *ast.DeclStmt: 28 | case *ast.DeferStmt: 29 | case *ast.EmptyStmt: 30 | case *ast.ExprStmt: 31 | case *ast.ForStmt: 32 | case *ast.GoStmt: 33 | case *ast.IfStmt: 34 | case *ast.IncDecStmt: 35 | case *ast.LabeledStmt: 36 | case *ast.RangeStmt: 37 | case *ast.ReturnStmt: 38 | case *ast.SelectStmt: 39 | case *ast.SendStmt: 40 | case *ast.SwitchStmt: 41 | case *ast.TypeSwitchStmt: 42 | } 43 | 44 | var kind ast.ObjKind 45 | switch kind { 46 | case ast.Bad: 47 | case ast.Con: 48 | case ast.Fun: 49 | case ast.Lbl: 50 | case ast.Pkg: 51 | case ast.Typ: 52 | case ast.Var: 53 | } 54 | ``` 55 | after applying fillswitch for the (type) switch statements. 56 | 57 | ## Installation 58 | 59 | ``` 60 | % go get -u github.com/davidrjenni/reftools/cmd/fillswitch 61 | ``` 62 | 63 | ## Usage 64 | 65 | ``` 66 | % fillswitch [-modified] -file= -offset= -line= 67 | ``` 68 | 69 | Flags: 70 | 71 | -file: filename 72 | -modified: read an archive of modified files from stdin 73 | -offset: byte offset of the (type) switch, optional if -line is present 74 | -line: line number of the (type) switch, optional if -offset is present 75 | 76 | If -offset as well as -line are present, then the tool first uses the 77 | more specific offset information. If there was no (type) switch found 78 | at the given offset, then the line information is used. 79 | -------------------------------------------------------------------------------- /cmd/fillswitch/fill.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 David R. Jenni. 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 | package main 6 | 7 | import ( 8 | "go/ast" 9 | "go/types" 10 | "sort" 11 | "strings" 12 | 13 | "golang.org/x/tools/go/loader" 14 | ) 15 | 16 | func fillSwitch(pkg *loader.PackageInfo, lprog *loader.Program, swtch ast.Stmt, typ types.Type) ast.Stmt { 17 | // Do not try to fill an empty switch statement (with no tag expression and therefore typ == nil). 18 | if typ == nil { 19 | return swtch 20 | } 21 | 22 | switch swtch := swtch.(type) { 23 | case *ast.SwitchStmt: 24 | existing := make(map[string]bool) 25 | // Don't add the identifier we switch over to the case statements. 26 | if id, ok := swtch.Tag.(*ast.Ident); ok { 27 | existing[id.Name] = true 28 | } 29 | for _, cc := range swtch.Body.List { 30 | for _, e := range cc.(*ast.CaseClause).List { 31 | existing[typeString(pkg.Pkg, pkg.Info.TypeOf(e))] = true 32 | } 33 | } 34 | for _, v := range findConstsAndVars(lprog, pkg.Pkg, typ) { 35 | name := ast.NewIdent(v.Name()) 36 | if imported(pkg.Pkg, v) { 37 | name = ast.NewIdent(v.Pkg().Name() + "." + v.Name()) 38 | } 39 | if !existing[v.Name()] { 40 | swtch.Body.List = append(swtch.Body.List, &ast.CaseClause{ 41 | List: []ast.Expr{name}, 42 | }) 43 | } 44 | } 45 | return swtch 46 | 47 | case *ast.TypeSwitchStmt: 48 | iface, ok := typ.Underlying().(*types.Interface) 49 | if !ok { 50 | return swtch 51 | } 52 | existing := make(map[string]bool) 53 | for _, cc := range swtch.Body.List { 54 | for _, e := range cc.(*ast.CaseClause).List { 55 | name := typeString(pkg.Pkg, pkg.Info.TypeOf(e)) 56 | existing[name] = true 57 | } 58 | } 59 | for _, t := range findTypes(lprog, pkg.Pkg, iface) { 60 | if ts := typeString(pkg.Pkg, t); !existing[ts] { 61 | swtch.Body.List = append(swtch.Body.List, &ast.CaseClause{ 62 | List: []ast.Expr{ast.NewIdent(ts)}, 63 | }) 64 | } 65 | } 66 | return swtch 67 | 68 | default: 69 | panic("unreachable") 70 | } 71 | } 72 | 73 | func findConstsAndVars(lprog *loader.Program, pkg *types.Package, typ types.Type) []types.Object { 74 | var vars []types.Object 75 | for _, info := range lprog.AllPackages { 76 | for _, obj := range info.Defs { 77 | switch obj := obj.(type) { 78 | case *types.Const: 79 | if visible(pkg, obj) && types.AssignableTo(obj.Type(), typ) { 80 | vars = append(vars, obj) 81 | } 82 | case *types.Var: 83 | if visible(pkg, obj) && !obj.IsField() && types.AssignableTo(obj.Type(), typ) { 84 | vars = append(vars, obj) 85 | } 86 | } 87 | } 88 | } 89 | 90 | sort.Sort(objsByString(vars)) 91 | return vars 92 | } 93 | 94 | func findTypes(lprog *loader.Program, pkg *types.Package, iface types.Type) []types.Type { 95 | var typs []types.Type 96 | 97 | err := types.Universe.Lookup("error").Type() 98 | if types.AssignableTo(err, iface) { 99 | typs = append(typs, err) 100 | } 101 | 102 | for _, info := range lprog.AllPackages { 103 | for _, obj := range info.Defs { 104 | obj, ok := obj.(*types.TypeName) 105 | if !ok || obj.IsAlias() || !visible(pkg, obj) { 106 | continue 107 | } 108 | 109 | t := obj.Type().(*types.Named) 110 | // Ignore iface itself and empty interfaces. 111 | if i, ok := t.Underlying().(*types.Interface); ok && (iface == i || i.NumMethods() == 0) { 112 | continue 113 | } 114 | 115 | if types.AssignableTo(t, iface) { 116 | typs = append(typs, t) 117 | } else if p := types.NewPointer(t); types.AssignableTo(p, iface) { 118 | typs = append(typs, p) 119 | } 120 | } 121 | } 122 | 123 | sort.Sort(typesByString(typs)) 124 | return typs 125 | } 126 | 127 | func imported(pkg *types.Package, obj types.Object) bool { 128 | return obj.Pkg() != pkg 129 | } 130 | 131 | func visible(pkg *types.Package, obj types.Object) bool { 132 | if obj.Pkg() == pkg { 133 | return true 134 | } 135 | if !obj.Exported() { 136 | return false 137 | } 138 | 139 | // Rough approximation at the "internal" rules. 140 | 141 | path := obj.Pkg().Path() 142 | i := 0 143 | 144 | switch { 145 | case strings.HasSuffix(path, "/internal"): 146 | i = len(path) - len("/internal") 147 | case strings.Contains(path, "/internal/"): 148 | i = strings.LastIndex(path, "/internal/") + 1 149 | case path == "internal", strings.HasPrefix(path, "internal/"): 150 | i = 0 151 | default: 152 | return true 153 | } 154 | if i > 0 { 155 | i-- 156 | } 157 | prefix := path[:i] 158 | return len(prefix) > 0 && strings.HasPrefix(pkg.Path(), prefix) 159 | } 160 | 161 | type typesByString []types.Type 162 | 163 | func (t typesByString) Len() int { return len(t) } 164 | func (t typesByString) Swap(i, j int) { t[i], t[j] = t[j], t[i] } 165 | func (t typesByString) Less(i, j int) bool { return t[i].String() < t[j].String() } 166 | 167 | type objsByString []types.Object 168 | 169 | func (o objsByString) Len() int { return len(o) } 170 | func (o objsByString) Swap(i, j int) { o[i], o[j] = o[j], o[i] } 171 | func (o objsByString) Less(i, j int) bool { return o[i].String() < o[j].String() } 172 | -------------------------------------------------------------------------------- /cmd/fillswitch/fill_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 David R. Jenni. 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 | package main 6 | 7 | import ( 8 | "bytes" 9 | "encoding/json" 10 | "io/ioutil" 11 | "path/filepath" 12 | "testing" 13 | ) 14 | 15 | func TestFillByOffset(t *testing.T) { 16 | tests := [...]struct { 17 | folder string 18 | offset int 19 | }{ 20 | {folder: "typeswitch_1", offset: 75}, 21 | {folder: "typeswitch_2", offset: 59}, 22 | {folder: "typeswitch_3", offset: 69}, 23 | {folder: "typeswitch_4", offset: 67}, 24 | {folder: "typeswitch_5", offset: 160}, 25 | {folder: "broken_typeswitch", offset: 146}, 26 | {folder: "switch_1", offset: 78}, 27 | {folder: "empty_switch", offset: 51}, 28 | {folder: "multipkgs", offset: 75}, 29 | } 30 | 31 | for _, test := range tests { 32 | path, err := absPath(filepath.Join("./testdata", test.folder, "input.go")) 33 | if err != nil { 34 | t.Fatalf("%s: %v\n", test.folder, err) 35 | } 36 | lprog, err := load(path, false) 37 | if err != nil { 38 | t.Fatalf("%s: %v\n", test.folder, err) 39 | } 40 | 41 | var buf bytes.Buffer 42 | if err = byOffset(lprog, path, test.offset, &buf); err != nil { 43 | t.Fatalf("%s: %v\n", test.folder, err) 44 | } 45 | 46 | var outs []output 47 | if err = json.NewDecoder(&buf).Decode(&outs); err != nil { 48 | t.Fatalf("%s: %v\n", test.folder, err) 49 | } 50 | if len(outs) != 1 { 51 | t.Fatalf("%s: expected len(outs) == 1\n", test.folder) 52 | } 53 | got := []byte(outs[0].Code) 54 | 55 | want, err := ioutil.ReadFile(filepath.Join("./testdata", test.folder, "output.golden")) 56 | if err != nil { 57 | t.Fatalf("%s: %v\n", test.folder, err) 58 | } 59 | 60 | if !bytes.Equal(got, want) { 61 | t.Errorf("%s:\ngot:\n%s\n\nwant:\n%s\n\n", test.folder, got, want) 62 | } 63 | } 64 | } 65 | 66 | func TestFillByLine(t *testing.T) { 67 | tests := [...]struct { 68 | folder string 69 | line int 70 | }{ 71 | {folder: "typeswitch_1", line: 6}, 72 | {folder: "typeswitch_2", line: 6}, 73 | {folder: "typeswitch_3", line: 9}, 74 | {folder: "typeswitch_4", line: 9}, 75 | {folder: "typeswitch_5", line: 10}, 76 | {folder: "broken_typeswitch", line: 7}, 77 | {folder: "switch_1", line: 7}, 78 | {folder: "empty_switch", line: 6}, 79 | } 80 | 81 | for _, test := range tests { 82 | path, err := absPath(filepath.Join("./testdata", test.folder, "input.go")) 83 | if err != nil { 84 | t.Fatalf("%s: %v\n", test.folder, err) 85 | } 86 | lprog, err := load(path, false) 87 | if err != nil { 88 | t.Fatalf("%s: %v\n", test.folder, err) 89 | } 90 | 91 | var buf bytes.Buffer 92 | if err = byLine(lprog, path, test.line, &buf); err != nil { 93 | t.Fatalf("%s: %v\n", test.folder, err) 94 | } 95 | 96 | var outs []output 97 | if err = json.NewDecoder(&buf).Decode(&outs); err != nil { 98 | t.Fatal(err) 99 | } 100 | if len(outs) != 1 { 101 | t.Fatalf("%s: expected len(outs) == 1\n", test.folder) 102 | } 103 | got := []byte(outs[0].Code) 104 | 105 | want, err := ioutil.ReadFile(filepath.Join("./testdata", test.folder, "output.golden")) 106 | if err != nil { 107 | t.Fatalf("%s: %v\n", test.folder, err) 108 | } 109 | 110 | if !bytes.Equal(got, want) { 111 | t.Errorf("%s:\ngot:\n%s\n\nwant:\n%s\n\n", test.folder, got, want) 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/broken_typeswitch/input.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import "go/ast" 4 | 5 | func test(decl *ast.FuncDecl) { 6 | // Error: cannot type switch on non-interface value decl (type *ast.FuncDecl) 7 | switch decl := decl.(type) { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/broken_typeswitch/output.golden: -------------------------------------------------------------------------------- 1 | switch decl := decl.(type) { 2 | } -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/empty_switch/input.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import _ "sort" 4 | 5 | func test() { 6 | switch { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/empty_switch/output.golden: -------------------------------------------------------------------------------- 1 | switch { 2 | } -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/multipkgs/input.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import "go/ast" 4 | 5 | func test(s ast.Stmt) { 6 | switch s := s.(type) { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/multipkgs/input_test.go: -------------------------------------------------------------------------------- 1 | package p_test 2 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/multipkgs/output.golden: -------------------------------------------------------------------------------- 1 | switch s := s.(type) { 2 | case *ast.AssignStmt: 3 | case *ast.BadStmt: 4 | case *ast.BlockStmt: 5 | case *ast.BranchStmt: 6 | case *ast.CaseClause: 7 | case *ast.CommClause: 8 | case *ast.DeclStmt: 9 | case *ast.DeferStmt: 10 | case *ast.EmptyStmt: 11 | case *ast.ExprStmt: 12 | case *ast.ForStmt: 13 | case *ast.GoStmt: 14 | case *ast.IfStmt: 15 | case *ast.IncDecStmt: 16 | case *ast.LabeledStmt: 17 | case *ast.RangeStmt: 18 | case *ast.ReturnStmt: 19 | case *ast.SelectStmt: 20 | case *ast.SendStmt: 21 | case *ast.SwitchStmt: 22 | case *ast.TypeSwitchStmt: 23 | } -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/switch_1/input.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import "go/ast" 4 | 5 | func test() { 6 | var kind ast.ObjKind 7 | switch kind { 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/switch_1/output.golden: -------------------------------------------------------------------------------- 1 | switch kind { 2 | case ast.Bad: 3 | case ast.Con: 4 | case ast.Fun: 5 | case ast.Lbl: 6 | case ast.Pkg: 7 | case ast.Typ: 8 | case ast.Var: 9 | } -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_1/input.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import "go/ast" 4 | 5 | func test(s ast.Stmt) { 6 | switch s := s.(type) { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_1/output.golden: -------------------------------------------------------------------------------- 1 | switch s := s.(type) { 2 | case *ast.AssignStmt: 3 | case *ast.BadStmt: 4 | case *ast.BlockStmt: 5 | case *ast.BranchStmt: 6 | case *ast.CaseClause: 7 | case *ast.CommClause: 8 | case *ast.DeclStmt: 9 | case *ast.DeferStmt: 10 | case *ast.EmptyStmt: 11 | case *ast.ExprStmt: 12 | case *ast.ForStmt: 13 | case *ast.GoStmt: 14 | case *ast.IfStmt: 15 | case *ast.IncDecStmt: 16 | case *ast.LabeledStmt: 17 | case *ast.RangeStmt: 18 | case *ast.ReturnStmt: 19 | case *ast.SelectStmt: 20 | case *ast.SendStmt: 21 | case *ast.SwitchStmt: 22 | case *ast.TypeSwitchStmt: 23 | } -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_2/input.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import "go/ast" 4 | 5 | func test(s ast.Stmt) { 6 | switch s.(type) { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_2/output.golden: -------------------------------------------------------------------------------- 1 | switch s.(type) { 2 | case *ast.AssignStmt: 3 | case *ast.BadStmt: 4 | case *ast.BlockStmt: 5 | case *ast.BranchStmt: 6 | case *ast.CaseClause: 7 | case *ast.CommClause: 8 | case *ast.DeclStmt: 9 | case *ast.DeferStmt: 10 | case *ast.EmptyStmt: 11 | case *ast.ExprStmt: 12 | case *ast.ForStmt: 13 | case *ast.GoStmt: 14 | case *ast.IfStmt: 15 | case *ast.IncDecStmt: 16 | case *ast.LabeledStmt: 17 | case *ast.RangeStmt: 18 | case *ast.ReturnStmt: 19 | case *ast.SelectStmt: 20 | case *ast.SendStmt: 21 | case *ast.SwitchStmt: 22 | case *ast.TypeSwitchStmt: 23 | } -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_3/input.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( 4 | "io" 5 | _ "os" 6 | ) 7 | 8 | func test(r io.Reader) { 9 | switch r := r.(type) { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_3/output.golden: -------------------------------------------------------------------------------- 1 | switch r := r.(type) { 2 | case *io.LimitedReader: 3 | case *io.PipeReader: 4 | case *io.SectionReader: 5 | case *os.File: 6 | case io.ReadCloser: 7 | case io.ReadSeeker: 8 | case io.ReadWriteCloser: 9 | case io.ReadWriteSeeker: 10 | case io.ReadWriter: 11 | } -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_4/input.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( 4 | "io" 5 | "os" 6 | ) 7 | 8 | func test(r io.Reader) { 9 | switch r := r.(type) { 10 | case *os.File: 11 | println("file") 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_4/output.golden: -------------------------------------------------------------------------------- 1 | switch r := r.(type) { 2 | case *os.File: 3 | println("file") 4 | case *io.LimitedReader: 5 | case *io.PipeReader: 6 | case *io.SectionReader: 7 | case io.ReadCloser: 8 | case io.ReadSeeker: 9 | case io.ReadWriteCloser: 10 | case io.ReadWriteSeeker: 11 | case io.ReadWriter: 12 | } -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_5/input.go: -------------------------------------------------------------------------------- 1 | package p 2 | 3 | import ( 4 | "io" 5 | 6 | _ "github.com/davidrjenni/reftools/cmd/fillswitch/testdata/typeswitch_5/internal/foo" 7 | ) 8 | 9 | func test(r io.Reader) { 10 | switch r := r.(type) { 11 | } 12 | } 13 | 14 | type panicReader struct{} 15 | 16 | func (r *panicReader) Read(p []byte) (int, error) { 17 | panic("not implemented") 18 | } 19 | 20 | type myReadWriter interface { 21 | Read(p []byte) (int, error) 22 | Writer(p []byte) (int, error) 23 | } 24 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_5/internal/foo/foo.go: -------------------------------------------------------------------------------- 1 | package foo 2 | 3 | type NopReader1 struct{} 4 | 5 | func (r *NopReader1) Read(p []byte) (int, error) { 6 | return 0, nil 7 | } 8 | 9 | type NopReader2 struct{} 10 | 11 | func (r NopReader2) Read(p []byte) (int, error) { 12 | return 0, nil 13 | } 14 | 15 | type unexportedNopReader {} 16 | 17 | func (r *unexportedNopReader) Read(p []byte) (int, error) { 18 | return 0, nil 19 | } 20 | -------------------------------------------------------------------------------- /cmd/fillswitch/testdata/typeswitch_5/output.golden: -------------------------------------------------------------------------------- 1 | switch r := r.(type) { 2 | case *panicReader: 3 | case *foo.NopReader1: 4 | case *io.LimitedReader: 5 | case *io.PipeReader: 6 | case *io.SectionReader: 7 | case myReadWriter: 8 | case foo.NopReader2: 9 | case io.ReadCloser: 10 | case io.ReadSeeker: 11 | case io.ReadWriteCloser: 12 | case io.ReadWriteSeeker: 13 | case io.ReadWriter: 14 | } -------------------------------------------------------------------------------- /cmd/fillswitch/typestring.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 David R. Jenni. 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 | // Plundered from go/types; customized. 6 | 7 | // Copyright (c) 2009 The Go Authors. All rights reserved. 8 | // 9 | // Redistribution and use in source and binary forms, with or without 10 | // modification, are permitted provided that the following conditions are 11 | // met: 12 | // 13 | // * Redistributions of source code must retain the above copyright 14 | // notice, this list of conditions and the following disclaimer. 15 | // * Redistributions in binary form must reproduce the above 16 | // copyright notice, this list of conditions and the following disclaimer 17 | // in the documentation and/or other materials provided with the 18 | // distribution. 19 | // * Neither the name of Google Inc. nor the names of its 20 | // contributors may be used to endorse or promote products derived from 21 | // this software without specific prior written permission. 22 | // 23 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | 35 | // This file implements printing of types. 36 | 37 | package main 38 | 39 | import ( 40 | "bytes" 41 | "fmt" 42 | "go/types" 43 | ) 44 | 45 | func typeString(pkg *types.Package, typ types.Type) string { 46 | var buf bytes.Buffer 47 | writeType(&buf, pkg, typ, make([]types.Type, 0, 8)) 48 | return buf.String() 49 | } 50 | 51 | func writeType(buf *bytes.Buffer, pkg *types.Package, typ types.Type, visited []types.Type) { 52 | // Theoretically, this is a quadratic lookup algorithm, but in 53 | // practice deeply nested composite types with unnamed component 54 | // types are uncommon. This code is likely more efficient than 55 | // using a map. 56 | for _, t := range visited { 57 | if t == typ { 58 | fmt.Fprintf(buf, "○%T", typ) // cycle to typ 59 | return 60 | } 61 | } 62 | visited = append(visited, typ) 63 | 64 | switch t := typ.(type) { 65 | case nil: 66 | buf.WriteString("nil") 67 | 68 | case *types.Basic: 69 | if t.Kind() == types.UnsafePointer { 70 | buf.WriteString("unsafe.") 71 | } 72 | buf.WriteString(t.Name()) 73 | 74 | case *types.Array: 75 | fmt.Fprintf(buf, "[%d]", t.Len()) 76 | writeType(buf, pkg, t.Elem(), visited) 77 | 78 | case *types.Slice: 79 | buf.WriteString("[]") 80 | writeType(buf, pkg, t.Elem(), visited) 81 | 82 | case *types.Struct: 83 | buf.WriteString("struct{") 84 | for i := 0; i < t.NumFields(); i++ { 85 | f := t.Field(i) 86 | if i > 0 { 87 | buf.WriteString("; ") 88 | } 89 | if !f.Anonymous() { 90 | buf.WriteString(f.Name()) 91 | buf.WriteByte(' ') 92 | } 93 | writeType(buf, pkg, f.Type(), visited) 94 | if tag := t.Tag(i); tag != "" { 95 | fmt.Fprintf(buf, " %q", tag) 96 | } 97 | } 98 | buf.WriteByte('}') 99 | 100 | case *types.Pointer: 101 | buf.WriteByte('*') 102 | writeType(buf, pkg, t.Elem(), visited) 103 | 104 | case *types.Tuple: 105 | writeTuple(buf, pkg, t, false, visited) 106 | 107 | case *types.Signature: 108 | buf.WriteString("func") 109 | writeSignature(buf, pkg, t, visited) 110 | 111 | case *types.Interface: 112 | // We write the source-level methods and embedded types rather 113 | // than the actual method set since resolved method signatures 114 | // may have non-printable cycles if parameters have anonymous 115 | // interface types that (directly or indirectly) embed the 116 | // current interface. For instance, consider the result type 117 | // of m: 118 | // 119 | // type T interface{ 120 | // m() interface{ T } 121 | // } 122 | // 123 | buf.WriteString("interface{") 124 | // print explicit interface methods and embedded types 125 | for i := 0; i < t.NumMethods(); i++ { 126 | m := t.Method(i) 127 | if i > 0 { 128 | buf.WriteString("; ") 129 | } 130 | buf.WriteString(m.Name()) 131 | writeSignature(buf, pkg, m.Type().(*types.Signature), visited) 132 | } 133 | for i := 0; i < t.NumEmbeddeds(); i++ { 134 | if i > 0 || t.NumMethods() > 0 { 135 | buf.WriteString("; ") 136 | } 137 | writeType(buf, pkg, t.EmbeddedType(i), visited) 138 | } 139 | buf.WriteByte('}') 140 | 141 | case *types.Map: 142 | buf.WriteString("map[") 143 | writeType(buf, pkg, t.Key(), visited) 144 | buf.WriteByte(']') 145 | writeType(buf, pkg, t.Elem(), visited) 146 | 147 | case *types.Chan: 148 | var s string 149 | var parens bool 150 | switch t.Dir() { 151 | case types.SendRecv: 152 | s = "chan " 153 | // chan (<-chan T) requires parentheses 154 | if c, _ := t.Elem().(*types.Chan); c != nil && c.Dir() == types.RecvOnly { 155 | parens = true 156 | } 157 | case types.SendOnly: 158 | s = "chan<- " 159 | case types.RecvOnly: 160 | s = "<-chan " 161 | default: 162 | panic("unreachable") 163 | } 164 | buf.WriteString(s) 165 | if parens { 166 | buf.WriteByte('(') 167 | } 168 | writeType(buf, pkg, t.Elem(), visited) 169 | if parens { 170 | buf.WriteByte(')') 171 | } 172 | 173 | case *types.Named: 174 | if pkg != t.Obj().Pkg() && t.Obj().Pkg() != nil { 175 | buf.WriteString(fmt.Sprintf("%s.%s", t.Obj().Pkg().Name(), t.Obj().Name())) 176 | } else { 177 | buf.WriteString(t.Obj().Name()) 178 | } 179 | 180 | default: 181 | // For externally defined implementations of Type. 182 | buf.WriteString(t.String()) 183 | } 184 | } 185 | 186 | func writeTuple(buf *bytes.Buffer, pkg *types.Package, tup *types.Tuple, variadic bool, visited []types.Type) { 187 | buf.WriteByte('(') 188 | if tup != nil { 189 | for i := 0; i < tup.Len(); i++ { 190 | v := tup.At(i) 191 | if i > 0 { 192 | buf.WriteString(", ") 193 | } 194 | if v.Name() != "" { 195 | buf.WriteString(v.Name()) 196 | buf.WriteByte(' ') 197 | } 198 | typ := v.Type() 199 | if variadic && i == tup.Len()-1 { 200 | if s, ok := typ.(*types.Slice); ok { 201 | buf.WriteString("...") 202 | typ = s.Elem() 203 | } else { 204 | // special case: 205 | // append(s, "foo"...) leads to signature func([]byte, string...) 206 | if t, ok := typ.Underlying().(*types.Basic); !ok || t.Kind() != types.String { 207 | panic("internal error: string type expected") 208 | } 209 | writeType(buf, pkg, typ, visited) 210 | buf.WriteString("...") 211 | continue 212 | } 213 | } 214 | writeType(buf, pkg, typ, visited) 215 | } 216 | } 217 | buf.WriteByte(')') 218 | } 219 | 220 | func writeSignature(buf *bytes.Buffer, pkg *types.Package, sig *types.Signature, visited []types.Type) { 221 | writeTuple(buf, pkg, sig.Params(), sig.Variadic(), visited) 222 | 223 | n := sig.Results().Len() 224 | if n == 0 { 225 | return // no result 226 | } 227 | 228 | buf.WriteByte(' ') 229 | if n == 1 && sig.Results().At(0).Name() == "" { 230 | // single unnamed result 231 | writeType(buf, pkg, sig.Results().At(0).Type(), visited) 232 | return 233 | } 234 | 235 | // multiple or named result(s) 236 | writeTuple(buf, pkg, sig.Results(), false, visited) 237 | } 238 | -------------------------------------------------------------------------------- /cmd/fixplurals/Readme.md: -------------------------------------------------------------------------------- 1 | # fixplurals [![Build Status](https://travis-ci.org/davidrjenni/reftools.svg?branch=master)](https://travis-ci.org/davidrjenni/reftools) [![Coverage Status](https://coveralls.io/repos/github/davidrjenni/reftools/badge.svg)](https://coveralls.io/github/davidrjenni/reftools) [![GoDoc](https://godoc.org/github.com/davidrjenni/reftools?status.svg)](https://godoc.org/github.com/davidrjenni/reftools/cmd/fixplurals) [![Go Report Card](https://goreportcard.com/badge/github.com/davidrjenni/reftools)](https://goreportcard.com/report/github.com/davidrjenni/reftools) 2 | 3 | fixplurals - remove redundant parameter and result types from function signatures 4 | 5 | --- 6 | 7 | For example, the following function signature: 8 | ``` 9 | func fun(a string, b string) (c string, d string) 10 | ``` 11 | becomes: 12 | ``` 13 | func fun(a, b string) (c, d string) 14 | ``` 15 | after applying fixplurals. 16 | 17 | ## Installation 18 | 19 | ``` 20 | % go get -u github.com/davidrjenni/reftools/cmd/fixplurals 21 | ``` 22 | 23 | ## Usage 24 | 25 | ``` 26 | % fixplurals [-dry] packages 27 | ``` 28 | 29 | Flags: 30 | 31 | -dry: changes are printed to stdout instead of rewriting the source files 32 | -------------------------------------------------------------------------------- /cmd/fixplurals/main.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2017 David R. Jenni. 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 | // Fixplurals removes redundant parameter and result types 6 | // from function signatures. 7 | // 8 | // For example, the following function signature: 9 | // func fun(a string, b string) (c string, d string) 10 | // becomes: 11 | // func fun(a, b string) (c, d string) 12 | // after applying fixplurals. 13 | // 14 | // Usage: 15 | // 16 | // % fixplurals [-dry] packages 17 | // 18 | // Flags: 19 | // 20 | // -dry: changes are printed to stdout instead of rewriting the source files 21 | // 22 | package main 23 | 24 | import ( 25 | "bytes" 26 | "flag" 27 | "fmt" 28 | "go/ast" 29 | "go/format" 30 | "go/parser" 31 | "go/token" 32 | "go/types" 33 | "io/ioutil" 34 | "log" 35 | 36 | "github.com/kisielk/gotool" 37 | "golang.org/x/tools/go/loader" 38 | ) 39 | 40 | func main() { 41 | log.SetFlags(0) 42 | log.SetPrefix("fixplurals: ") 43 | 44 | dryRun := flag.Bool("dry", false, "dry run: print changes to stdout") 45 | flag.Parse() 46 | 47 | importPaths := gotool.ImportPaths(flag.Args()) 48 | if len(importPaths) == 0 { 49 | return 50 | } 51 | 52 | conf := loader.Config{ParserMode: parser.ParseComments} 53 | for _, importPath := range importPaths { 54 | conf.ImportWithTests(importPath) 55 | } 56 | 57 | prog, err := conf.Load() 58 | if err != nil { 59 | log.Fatal(err) 60 | } 61 | 62 | for _, pkg := range prog.InitialPackages() { 63 | for _, file := range pkg.Files { 64 | filename := conf.Fset.File(file.Pos()).Name() 65 | ast.Inspect(file, func(node ast.Node) bool { 66 | if f, ok := node.(*ast.FuncDecl); ok { 67 | var before []byte 68 | if *dryRun { 69 | if before, err = printNode(f.Type, prog.Fset); err != nil { 70 | log.Fatal(err) 71 | } 72 | } 73 | ch1 := fixPlurals(pkg.Info, f.Type.Params) 74 | ch2 := fixPlurals(pkg.Info, f.Type.Results) 75 | if ch1 || ch2 { 76 | if *dryRun { 77 | after, err := printNode(f.Type, prog.Fset) 78 | if err != nil { 79 | log.Fatal(err) 80 | } 81 | fmt.Printf("--- %s\nbefore: %s\nafter: %s\n\n", filename, string(before), string(after)) 82 | } else { 83 | src, err := printNode(file, prog.Fset) 84 | if err != nil { 85 | log.Fatal(err) 86 | } 87 | if err := ioutil.WriteFile(filename, src, 0644); err != nil { 88 | log.Fatal(err) 89 | } 90 | } 91 | } 92 | } 93 | return true 94 | }) 95 | } 96 | } 97 | } 98 | 99 | func printNode(n ast.Node, fset *token.FileSet) ([]byte, error) { 100 | var buf bytes.Buffer 101 | if err := format.Node(&buf, fset, n); err != nil { 102 | return nil, err 103 | } 104 | return buf.Bytes(), nil 105 | } 106 | 107 | func fixPlurals(info types.Info, fields *ast.FieldList) (changed bool) { 108 | if fields == nil || fields.List == nil { 109 | return 110 | } 111 | 112 | var prev *ast.Field 113 | for i := len(fields.List) - 1; i >= 0; i-- { 114 | field := fields.List[i] 115 | if i != len(fields.List)-1 && len(field.Names) > 0 && types.Identical(info.Types[prev.Type].Type, info.Types[field.Type].Type) { 116 | prev.Names = append(field.Names, prev.Names...) 117 | copy(fields.List[i:], fields.List[i+1:]) 118 | fields.List[len(fields.List)-1] = nil 119 | fields.List = fields.List[:len(fields.List)-1] 120 | changed = true 121 | } else { 122 | prev = field 123 | } 124 | } 125 | return changed 126 | } 127 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/davidrjenni/reftools 2 | 3 | require ( 4 | github.com/kisielk/gotool v1.0.0 5 | golang.org/x/tools v0.17.0 6 | ) 7 | 8 | require golang.org/x/mod v0.15.0 // indirect 9 | 10 | go 1.21 11 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= 2 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 3 | golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8= 4 | golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 5 | golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= 6 | golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 7 | golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= 8 | golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= 9 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | go: 4 | - 1.2 5 | - 1.3 6 | - 1.4 7 | - 1.5 8 | - 1.6 9 | - 1.7 10 | - 1.8 11 | - 1.9 12 | - master 13 | matrix: 14 | allow_failures: 15 | - go: master 16 | fast_finish: true 17 | install: 18 | - # Skip. 19 | script: 20 | - go get -t -v ./... 21 | - diff -u <(echo -n) <(gofmt -d .) 22 | - go tool vet . 23 | - go test -v -race ./... 24 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/LEGAL: -------------------------------------------------------------------------------- 1 | All the files in this distribution are covered under either the MIT 2 | license (see the file LICENSE) except some files mentioned below. 3 | 4 | match.go, match_test.go: 5 | 6 | Copyright (c) 2009 The Go Authors. All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other materials provided with the 17 | distribution. 18 | * Neither the name of Google Inc. nor the names of its 19 | contributors may be used to endorse or promote products derived from 20 | this software without specific prior written permission. 21 | 22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 25 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 26 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 28 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Kamil Kisiel 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/README.md: -------------------------------------------------------------------------------- 1 | gotool 2 | ====== 3 | [![GoDoc](https://godoc.org/github.com/kisielk/gotool?status.svg)](https://godoc.org/github.com/kisielk/gotool) 4 | [![Build Status](https://travis-ci.org/kisielk/gotool.svg?branch=master)](https://travis-ci.org/kisielk/gotool) 5 | 6 | Package gotool contains utility functions used to implement the standard "cmd/go" tool, provided as a convenience to developers who want to write tools with similar semantics. 7 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/go13.go: -------------------------------------------------------------------------------- 1 | // +build !go1.4 2 | 3 | package gotool 4 | 5 | import ( 6 | "go/build" 7 | "path/filepath" 8 | "runtime" 9 | ) 10 | 11 | var gorootSrc = filepath.Join(runtime.GOROOT(), "src", "pkg") 12 | 13 | func shouldIgnoreImport(p *build.Package) bool { 14 | return true 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/go14-15.go: -------------------------------------------------------------------------------- 1 | // +build go1.4,!go1.6 2 | 3 | package gotool 4 | 5 | import ( 6 | "go/build" 7 | "path/filepath" 8 | "runtime" 9 | ) 10 | 11 | var gorootSrc = filepath.Join(runtime.GOROOT(), "src") 12 | 13 | func shouldIgnoreImport(p *build.Package) bool { 14 | return true 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/go16-18.go: -------------------------------------------------------------------------------- 1 | // +build go1.6,!go1.9 2 | 3 | package gotool 4 | 5 | import ( 6 | "go/build" 7 | "path/filepath" 8 | "runtime" 9 | ) 10 | 11 | var gorootSrc = filepath.Join(runtime.GOROOT(), "src") 12 | 13 | func shouldIgnoreImport(p *build.Package) bool { 14 | return p == nil || len(p.InvalidGoFiles) == 0 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/internal/load/path.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 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 | // +build go1.9 6 | 7 | package load 8 | 9 | import ( 10 | "strings" 11 | ) 12 | 13 | // hasPathPrefix reports whether the path s begins with the 14 | // elements in prefix. 15 | func hasPathPrefix(s, prefix string) bool { 16 | switch { 17 | default: 18 | return false 19 | case len(s) == len(prefix): 20 | return s == prefix 21 | case len(s) > len(prefix): 22 | if prefix != "" && prefix[len(prefix)-1] == '/' { 23 | return strings.HasPrefix(s, prefix) 24 | } 25 | return s[len(prefix)] == '/' && s[:len(prefix)] == prefix 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/internal/load/pkg.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 | // +build go1.9 6 | 7 | // Package load loads packages. 8 | package load 9 | 10 | import ( 11 | "strings" 12 | ) 13 | 14 | // isStandardImportPath reports whether $GOROOT/src/path should be considered 15 | // part of the standard distribution. For historical reasons we allow people to add 16 | // their own code to $GOROOT instead of using $GOPATH, but we assume that 17 | // code will start with a domain name (dot in the first element). 18 | func isStandardImportPath(path string) bool { 19 | i := strings.Index(path, "/") 20 | if i < 0 { 21 | i = len(path) 22 | } 23 | elem := path[:i] 24 | return !strings.Contains(elem, ".") 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/match.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2009 The Go Authors. All rights reserved. 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are 5 | // met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above 10 | // copyright notice, this list of conditions and the following disclaimer 11 | // in the documentation and/or other materials provided with the 12 | // distribution. 13 | // * Neither the name of Google Inc. nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | // +build go1.9 30 | 31 | package gotool 32 | 33 | import ( 34 | "path/filepath" 35 | 36 | "github.com/kisielk/gotool/internal/load" 37 | ) 38 | 39 | // importPaths returns the import paths to use for the given command line. 40 | func (c *Context) importPaths(args []string) []string { 41 | lctx := load.Context{ 42 | BuildContext: c.BuildContext, 43 | GOROOTsrc: c.joinPath(c.BuildContext.GOROOT, "src"), 44 | } 45 | return lctx.ImportPaths(args) 46 | } 47 | 48 | // joinPath calls c.BuildContext.JoinPath (if not nil) or else filepath.Join. 49 | // 50 | // It's a copy of the unexported build.Context.joinPath helper. 51 | func (c *Context) joinPath(elem ...string) string { 52 | if f := c.BuildContext.JoinPath; f != nil { 53 | return f(elem...) 54 | } 55 | return filepath.Join(elem...) 56 | } 57 | -------------------------------------------------------------------------------- /vendor/github.com/kisielk/gotool/tool.go: -------------------------------------------------------------------------------- 1 | // Package gotool contains utility functions used to implement the standard 2 | // "cmd/go" tool, provided as a convenience to developers who want to write 3 | // tools with similar semantics. 4 | package gotool 5 | 6 | import "go/build" 7 | 8 | // Export functions here to make it easier to keep the implementations up to date with upstream. 9 | 10 | // DefaultContext is the default context that uses build.Default. 11 | var DefaultContext = Context{ 12 | BuildContext: build.Default, 13 | } 14 | 15 | // A Context specifies the supporting context. 16 | type Context struct { 17 | // BuildContext is the build.Context that is used when computing import paths. 18 | BuildContext build.Context 19 | } 20 | 21 | // ImportPaths returns the import paths to use for the given command line. 22 | // 23 | // The path "all" is expanded to all packages in $GOPATH and $GOROOT. 24 | // The path "std" is expanded to all packages in the Go standard library. 25 | // The path "cmd" is expanded to all Go standard commands. 26 | // The string "..." is treated as a wildcard within a path. 27 | // When matching recursively, directories are ignored if they are prefixed with 28 | // a dot or an underscore (such as ".foo" or "_foo"), or are named "testdata". 29 | // Relative import paths are not converted to full import paths. 30 | // If args is empty, a single element "." is returned. 31 | func (c *Context) ImportPaths(args []string) []string { 32 | return c.importPaths(args) 33 | } 34 | 35 | // ImportPaths returns the import paths to use for the given command line 36 | // using default context. 37 | // 38 | // The path "all" is expanded to all packages in $GOPATH and $GOROOT. 39 | // The path "std" is expanded to all packages in the Go standard library. 40 | // The path "cmd" is expanded to all Go standard commands. 41 | // The string "..." is treated as a wildcard within a path. 42 | // When matching recursively, directories are ignored if they are prefixed with 43 | // a dot or an underscore (such as ".foo" or "_foo"), or are named "testdata". 44 | // Relative import paths are not converted to full import paths. 45 | // If args is empty, a single element "." is returned. 46 | func ImportPaths(args []string) []string { 47 | return DefaultContext.importPaths(args) 48 | } 49 | -------------------------------------------------------------------------------- /vendor/golang.org/x/mod/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/mod/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/ast/astutil/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 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 | package astutil 6 | 7 | import "go/ast" 8 | 9 | // Unparen returns e with any enclosing parentheses stripped. 10 | func Unparen(e ast.Expr) ast.Expr { 11 | for { 12 | p, ok := e.(*ast.ParenExpr) 13 | if !ok { 14 | return e 15 | } 16 | e = p.X 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/buildutil/allpackages.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 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 | // Package buildutil provides utilities related to the go/build 6 | // package in the standard library. 7 | // 8 | // All I/O is done via the build.Context file system interface, which must 9 | // be concurrency-safe. 10 | package buildutil // import "golang.org/x/tools/go/buildutil" 11 | 12 | import ( 13 | "go/build" 14 | "os" 15 | "path/filepath" 16 | "sort" 17 | "strings" 18 | "sync" 19 | ) 20 | 21 | // AllPackages returns the package path of each Go package in any source 22 | // directory of the specified build context (e.g. $GOROOT or an element 23 | // of $GOPATH). Errors are ignored. The results are sorted. 24 | // All package paths are canonical, and thus may contain "/vendor/". 25 | // 26 | // The result may include import paths for directories that contain no 27 | // *.go files, such as "archive" (in $GOROOT/src). 28 | // 29 | // All I/O is done via the build.Context file system interface, 30 | // which must be concurrency-safe. 31 | func AllPackages(ctxt *build.Context) []string { 32 | var list []string 33 | ForEachPackage(ctxt, func(pkg string, _ error) { 34 | list = append(list, pkg) 35 | }) 36 | sort.Strings(list) 37 | return list 38 | } 39 | 40 | // ForEachPackage calls the found function with the package path of 41 | // each Go package it finds in any source directory of the specified 42 | // build context (e.g. $GOROOT or an element of $GOPATH). 43 | // All package paths are canonical, and thus may contain "/vendor/". 44 | // 45 | // If the package directory exists but could not be read, the second 46 | // argument to the found function provides the error. 47 | // 48 | // All I/O is done via the build.Context file system interface, 49 | // which must be concurrency-safe. 50 | func ForEachPackage(ctxt *build.Context, found func(importPath string, err error)) { 51 | ch := make(chan item) 52 | 53 | var wg sync.WaitGroup 54 | for _, root := range ctxt.SrcDirs() { 55 | root := root 56 | wg.Add(1) 57 | go func() { 58 | allPackages(ctxt, root, ch) 59 | wg.Done() 60 | }() 61 | } 62 | go func() { 63 | wg.Wait() 64 | close(ch) 65 | }() 66 | 67 | // All calls to found occur in the caller's goroutine. 68 | for i := range ch { 69 | found(i.importPath, i.err) 70 | } 71 | } 72 | 73 | type item struct { 74 | importPath string 75 | err error // (optional) 76 | } 77 | 78 | // We use a process-wide counting semaphore to limit 79 | // the number of parallel calls to ReadDir. 80 | var ioLimit = make(chan bool, 20) 81 | 82 | func allPackages(ctxt *build.Context, root string, ch chan<- item) { 83 | root = filepath.Clean(root) + string(os.PathSeparator) 84 | 85 | var wg sync.WaitGroup 86 | 87 | var walkDir func(dir string) 88 | walkDir = func(dir string) { 89 | // Avoid .foo, _foo, and testdata directory trees. 90 | base := filepath.Base(dir) 91 | if base == "" || base[0] == '.' || base[0] == '_' || base == "testdata" { 92 | return 93 | } 94 | 95 | pkg := filepath.ToSlash(strings.TrimPrefix(dir, root)) 96 | 97 | // Prune search if we encounter any of these import paths. 98 | switch pkg { 99 | case "builtin": 100 | return 101 | } 102 | 103 | ioLimit <- true 104 | files, err := ReadDir(ctxt, dir) 105 | <-ioLimit 106 | if pkg != "" || err != nil { 107 | ch <- item{pkg, err} 108 | } 109 | for _, fi := range files { 110 | fi := fi 111 | if fi.IsDir() { 112 | wg.Add(1) 113 | go func() { 114 | walkDir(filepath.Join(dir, fi.Name())) 115 | wg.Done() 116 | }() 117 | } 118 | } 119 | } 120 | 121 | walkDir(root) 122 | wg.Wait() 123 | } 124 | 125 | // ExpandPatterns returns the set of packages matched by patterns, 126 | // which may have the following forms: 127 | // 128 | // golang.org/x/tools/cmd/guru # a single package 129 | // golang.org/x/tools/... # all packages beneath dir 130 | // ... # the entire workspace. 131 | // 132 | // Order is significant: a pattern preceded by '-' removes matching 133 | // packages from the set. For example, these patterns match all encoding 134 | // packages except encoding/xml: 135 | // 136 | // encoding/... -encoding/xml 137 | // 138 | // A trailing slash in a pattern is ignored. (Path components of Go 139 | // package names are separated by slash, not the platform's path separator.) 140 | func ExpandPatterns(ctxt *build.Context, patterns []string) map[string]bool { 141 | // TODO(adonovan): support other features of 'go list': 142 | // - "std"/"cmd"/"all" meta-packages 143 | // - "..." not at the end of a pattern 144 | // - relative patterns using "./" or "../" prefix 145 | 146 | pkgs := make(map[string]bool) 147 | doPkg := func(pkg string, neg bool) { 148 | if neg { 149 | delete(pkgs, pkg) 150 | } else { 151 | pkgs[pkg] = true 152 | } 153 | } 154 | 155 | // Scan entire workspace if wildcards are present. 156 | // TODO(adonovan): opt: scan only the necessary subtrees of the workspace. 157 | var all []string 158 | for _, arg := range patterns { 159 | if strings.HasSuffix(arg, "...") { 160 | all = AllPackages(ctxt) 161 | break 162 | } 163 | } 164 | 165 | for _, arg := range patterns { 166 | if arg == "" { 167 | continue 168 | } 169 | 170 | neg := arg[0] == '-' 171 | if neg { 172 | arg = arg[1:] 173 | } 174 | 175 | if arg == "..." { 176 | // ... matches all packages 177 | for _, pkg := range all { 178 | doPkg(pkg, neg) 179 | } 180 | } else if dir := strings.TrimSuffix(arg, "/..."); dir != arg { 181 | // dir/... matches all packages beneath dir 182 | for _, pkg := range all { 183 | if strings.HasPrefix(pkg, dir) && 184 | (len(pkg) == len(dir) || pkg[len(dir)] == '/') { 185 | doPkg(pkg, neg) 186 | } 187 | } 188 | } else { 189 | // single package 190 | doPkg(strings.TrimSuffix(arg, "/"), neg) 191 | } 192 | } 193 | 194 | return pkgs 195 | } 196 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/buildutil/fakecontext.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 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 | package buildutil 6 | 7 | import ( 8 | "fmt" 9 | "go/build" 10 | "io" 11 | "os" 12 | "path" 13 | "path/filepath" 14 | "sort" 15 | "strings" 16 | "time" 17 | ) 18 | 19 | // FakeContext returns a build.Context for the fake file tree specified 20 | // by pkgs, which maps package import paths to a mapping from file base 21 | // names to contents. 22 | // 23 | // The fake Context has a GOROOT of "/go" and no GOPATH, and overrides 24 | // the necessary file access methods to read from memory instead of the 25 | // real file system. 26 | // 27 | // Unlike a real file tree, the fake one has only two levels---packages 28 | // and files---so ReadDir("/go/src/") returns all packages under 29 | // /go/src/ including, for instance, "math" and "math/big". 30 | // ReadDir("/go/src/math/big") would return all the files in the 31 | // "math/big" package. 32 | func FakeContext(pkgs map[string]map[string]string) *build.Context { 33 | clean := func(filename string) string { 34 | f := path.Clean(filepath.ToSlash(filename)) 35 | // Removing "/go/src" while respecting segment 36 | // boundaries has this unfortunate corner case: 37 | if f == "/go/src" { 38 | return "" 39 | } 40 | return strings.TrimPrefix(f, "/go/src/") 41 | } 42 | 43 | ctxt := build.Default // copy 44 | ctxt.GOROOT = "/go" 45 | ctxt.GOPATH = "" 46 | ctxt.Compiler = "gc" 47 | ctxt.IsDir = func(dir string) bool { 48 | dir = clean(dir) 49 | if dir == "" { 50 | return true // needed by (*build.Context).SrcDirs 51 | } 52 | return pkgs[dir] != nil 53 | } 54 | ctxt.ReadDir = func(dir string) ([]os.FileInfo, error) { 55 | dir = clean(dir) 56 | var fis []os.FileInfo 57 | if dir == "" { 58 | // enumerate packages 59 | for importPath := range pkgs { 60 | fis = append(fis, fakeDirInfo(importPath)) 61 | } 62 | } else { 63 | // enumerate files of package 64 | for basename := range pkgs[dir] { 65 | fis = append(fis, fakeFileInfo(basename)) 66 | } 67 | } 68 | sort.Sort(byName(fis)) 69 | return fis, nil 70 | } 71 | ctxt.OpenFile = func(filename string) (io.ReadCloser, error) { 72 | filename = clean(filename) 73 | dir, base := path.Split(filename) 74 | content, ok := pkgs[path.Clean(dir)][base] 75 | if !ok { 76 | return nil, fmt.Errorf("file not found: %s", filename) 77 | } 78 | return io.NopCloser(strings.NewReader(content)), nil 79 | } 80 | ctxt.IsAbsPath = func(path string) bool { 81 | path = filepath.ToSlash(path) 82 | // Don't rely on the default (filepath.Path) since on 83 | // Windows, it reports virtual paths as non-absolute. 84 | return strings.HasPrefix(path, "/") 85 | } 86 | return &ctxt 87 | } 88 | 89 | type byName []os.FileInfo 90 | 91 | func (s byName) Len() int { return len(s) } 92 | func (s byName) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 93 | func (s byName) Less(i, j int) bool { return s[i].Name() < s[j].Name() } 94 | 95 | type fakeFileInfo string 96 | 97 | func (fi fakeFileInfo) Name() string { return string(fi) } 98 | func (fakeFileInfo) Sys() interface{} { return nil } 99 | func (fakeFileInfo) ModTime() time.Time { return time.Time{} } 100 | func (fakeFileInfo) IsDir() bool { return false } 101 | func (fakeFileInfo) Size() int64 { return 0 } 102 | func (fakeFileInfo) Mode() os.FileMode { return 0644 } 103 | 104 | type fakeDirInfo string 105 | 106 | func (fd fakeDirInfo) Name() string { return string(fd) } 107 | func (fakeDirInfo) Sys() interface{} { return nil } 108 | func (fakeDirInfo) ModTime() time.Time { return time.Time{} } 109 | func (fakeDirInfo) IsDir() bool { return true } 110 | func (fakeDirInfo) Size() int64 { return 0 } 111 | func (fakeDirInfo) Mode() os.FileMode { return 0755 } 112 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/buildutil/overlay.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | package buildutil 6 | 7 | import ( 8 | "bufio" 9 | "bytes" 10 | "fmt" 11 | "go/build" 12 | "io" 13 | "path/filepath" 14 | "strconv" 15 | "strings" 16 | ) 17 | 18 | // OverlayContext overlays a build.Context with additional files from 19 | // a map. Files in the map take precedence over other files. 20 | // 21 | // In addition to plain string comparison, two file names are 22 | // considered equal if their base names match and their directory 23 | // components point at the same directory on the file system. That is, 24 | // symbolic links are followed for directories, but not files. 25 | // 26 | // A common use case for OverlayContext is to allow editors to pass in 27 | // a set of unsaved, modified files. 28 | // 29 | // Currently, only the Context.OpenFile function will respect the 30 | // overlay. This may change in the future. 31 | func OverlayContext(orig *build.Context, overlay map[string][]byte) *build.Context { 32 | // TODO(dominikh): Implement IsDir, HasSubdir and ReadDir 33 | 34 | rc := func(data []byte) (io.ReadCloser, error) { 35 | return io.NopCloser(bytes.NewBuffer(data)), nil 36 | } 37 | 38 | copy := *orig // make a copy 39 | ctxt := © 40 | ctxt.OpenFile = func(path string) (io.ReadCloser, error) { 41 | // Fast path: names match exactly. 42 | if content, ok := overlay[path]; ok { 43 | return rc(content) 44 | } 45 | 46 | // Slow path: check for same file under a different 47 | // alias, perhaps due to a symbolic link. 48 | for filename, content := range overlay { 49 | if sameFile(path, filename) { 50 | return rc(content) 51 | } 52 | } 53 | 54 | return OpenFile(orig, path) 55 | } 56 | return ctxt 57 | } 58 | 59 | // ParseOverlayArchive parses an archive containing Go files and their 60 | // contents. The result is intended to be used with OverlayContext. 61 | // 62 | // # Archive format 63 | // 64 | // The archive consists of a series of files. Each file consists of a 65 | // name, a decimal file size and the file contents, separated by 66 | // newlines. No newline follows after the file contents. 67 | func ParseOverlayArchive(archive io.Reader) (map[string][]byte, error) { 68 | overlay := make(map[string][]byte) 69 | r := bufio.NewReader(archive) 70 | for { 71 | // Read file name. 72 | filename, err := r.ReadString('\n') 73 | if err != nil { 74 | if err == io.EOF { 75 | break // OK 76 | } 77 | return nil, fmt.Errorf("reading archive file name: %v", err) 78 | } 79 | filename = filepath.Clean(strings.TrimSpace(filename)) 80 | 81 | // Read file size. 82 | sz, err := r.ReadString('\n') 83 | if err != nil { 84 | return nil, fmt.Errorf("reading size of archive file %s: %v", filename, err) 85 | } 86 | sz = strings.TrimSpace(sz) 87 | size, err := strconv.ParseUint(sz, 10, 32) 88 | if err != nil { 89 | return nil, fmt.Errorf("parsing size of archive file %s: %v", filename, err) 90 | } 91 | 92 | // Read file content. 93 | content := make([]byte, size) 94 | if _, err := io.ReadFull(r, content); err != nil { 95 | return nil, fmt.Errorf("reading archive file %s: %v", filename, err) 96 | } 97 | overlay[filename] = content 98 | } 99 | 100 | return overlay, nil 101 | } 102 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/buildutil/tags.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 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 | package buildutil 6 | 7 | // This logic was copied from stringsFlag from $GOROOT/src/cmd/go/build.go. 8 | 9 | import "fmt" 10 | 11 | const TagsFlagDoc = "a list of `build tags` to consider satisfied during the build. " + 12 | "For more information about build tags, see the description of " + 13 | "build constraints in the documentation for the go/build package" 14 | 15 | // TagsFlag is an implementation of the flag.Value and flag.Getter interfaces that parses 16 | // a flag value in the same manner as go build's -tags flag and 17 | // populates a []string slice. 18 | // 19 | // See $GOROOT/src/go/build/doc.go for description of build tags. 20 | // See $GOROOT/src/cmd/go/doc.go for description of 'go build -tags' flag. 21 | // 22 | // Example: 23 | // 24 | // flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc) 25 | type TagsFlag []string 26 | 27 | func (v *TagsFlag) Set(s string) error { 28 | var err error 29 | *v, err = splitQuotedFields(s) 30 | if *v == nil { 31 | *v = []string{} 32 | } 33 | return err 34 | } 35 | 36 | func (v *TagsFlag) Get() interface{} { return *v } 37 | 38 | func splitQuotedFields(s string) ([]string, error) { 39 | // Split fields allowing '' or "" around elements. 40 | // Quotes further inside the string do not count. 41 | var f []string 42 | for len(s) > 0 { 43 | for len(s) > 0 && isSpaceByte(s[0]) { 44 | s = s[1:] 45 | } 46 | if len(s) == 0 { 47 | break 48 | } 49 | // Accepted quoted string. No unescaping inside. 50 | if s[0] == '"' || s[0] == '\'' { 51 | quote := s[0] 52 | s = s[1:] 53 | i := 0 54 | for i < len(s) && s[i] != quote { 55 | i++ 56 | } 57 | if i >= len(s) { 58 | return nil, fmt.Errorf("unterminated %c string", quote) 59 | } 60 | f = append(f, s[:i]) 61 | s = s[i+1:] 62 | continue 63 | } 64 | i := 0 65 | for i < len(s) && !isSpaceByte(s[i]) { 66 | i++ 67 | } 68 | f = append(f, s[:i]) 69 | s = s[i:] 70 | } 71 | return f, nil 72 | } 73 | 74 | func (v *TagsFlag) String() string { 75 | return "" 76 | } 77 | 78 | func isSpaceByte(c byte) bool { 79 | return c == ' ' || c == '\t' || c == '\n' || c == '\r' 80 | } 81 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/buildutil/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 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 | package buildutil 6 | 7 | import ( 8 | "fmt" 9 | "go/ast" 10 | "go/build" 11 | "go/parser" 12 | "go/token" 13 | "io" 14 | "io/ioutil" 15 | "os" 16 | "path" 17 | "path/filepath" 18 | "strings" 19 | ) 20 | 21 | // ParseFile behaves like parser.ParseFile, 22 | // but uses the build context's file system interface, if any. 23 | // 24 | // If file is not absolute (as defined by IsAbsPath), the (dir, file) 25 | // components are joined using JoinPath; dir must be absolute. 26 | // 27 | // The displayPath function, if provided, is used to transform the 28 | // filename that will be attached to the ASTs. 29 | // 30 | // TODO(adonovan): call this from go/loader.parseFiles when the tree thaws. 31 | func ParseFile(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, file string, mode parser.Mode) (*ast.File, error) { 32 | if !IsAbsPath(ctxt, file) { 33 | file = JoinPath(ctxt, dir, file) 34 | } 35 | rd, err := OpenFile(ctxt, file) 36 | if err != nil { 37 | return nil, err 38 | } 39 | defer rd.Close() // ignore error 40 | if displayPath != nil { 41 | file = displayPath(file) 42 | } 43 | return parser.ParseFile(fset, file, rd, mode) 44 | } 45 | 46 | // ContainingPackage returns the package containing filename. 47 | // 48 | // If filename is not absolute, it is interpreted relative to working directory dir. 49 | // All I/O is via the build context's file system interface, if any. 50 | // 51 | // The '...Files []string' fields of the resulting build.Package are not 52 | // populated (build.FindOnly mode). 53 | func ContainingPackage(ctxt *build.Context, dir, filename string) (*build.Package, error) { 54 | if !IsAbsPath(ctxt, filename) { 55 | filename = JoinPath(ctxt, dir, filename) 56 | } 57 | 58 | // We must not assume the file tree uses 59 | // "/" always, 60 | // `\` always, 61 | // or os.PathSeparator (which varies by platform), 62 | // but to make any progress, we are forced to assume that 63 | // paths will not use `\` unless the PathSeparator 64 | // is also `\`, thus we can rely on filepath.ToSlash for some sanity. 65 | 66 | dirSlash := path.Dir(filepath.ToSlash(filename)) + "/" 67 | 68 | // We assume that no source root (GOPATH[i] or GOROOT) contains any other. 69 | for _, srcdir := range ctxt.SrcDirs() { 70 | srcdirSlash := filepath.ToSlash(srcdir) + "/" 71 | if importPath, ok := HasSubdir(ctxt, srcdirSlash, dirSlash); ok { 72 | return ctxt.Import(importPath, dir, build.FindOnly) 73 | } 74 | } 75 | 76 | return nil, fmt.Errorf("can't find package containing %s", filename) 77 | } 78 | 79 | // -- Effective methods of file system interface ------------------------- 80 | 81 | // (go/build.Context defines these as methods, but does not export them.) 82 | 83 | // HasSubdir calls ctxt.HasSubdir (if not nil) or else uses 84 | // the local file system to answer the question. 85 | func HasSubdir(ctxt *build.Context, root, dir string) (rel string, ok bool) { 86 | if f := ctxt.HasSubdir; f != nil { 87 | return f(root, dir) 88 | } 89 | 90 | // Try using paths we received. 91 | if rel, ok = hasSubdir(root, dir); ok { 92 | return 93 | } 94 | 95 | // Try expanding symlinks and comparing 96 | // expanded against unexpanded and 97 | // expanded against expanded. 98 | rootSym, _ := filepath.EvalSymlinks(root) 99 | dirSym, _ := filepath.EvalSymlinks(dir) 100 | 101 | if rel, ok = hasSubdir(rootSym, dir); ok { 102 | return 103 | } 104 | if rel, ok = hasSubdir(root, dirSym); ok { 105 | return 106 | } 107 | return hasSubdir(rootSym, dirSym) 108 | } 109 | 110 | func hasSubdir(root, dir string) (rel string, ok bool) { 111 | const sep = string(filepath.Separator) 112 | root = filepath.Clean(root) 113 | if !strings.HasSuffix(root, sep) { 114 | root += sep 115 | } 116 | 117 | dir = filepath.Clean(dir) 118 | if !strings.HasPrefix(dir, root) { 119 | return "", false 120 | } 121 | 122 | return filepath.ToSlash(dir[len(root):]), true 123 | } 124 | 125 | // FileExists returns true if the specified file exists, 126 | // using the build context's file system interface. 127 | func FileExists(ctxt *build.Context, path string) bool { 128 | if ctxt.OpenFile != nil { 129 | r, err := ctxt.OpenFile(path) 130 | if err != nil { 131 | return false 132 | } 133 | r.Close() // ignore error 134 | return true 135 | } 136 | _, err := os.Stat(path) 137 | return err == nil 138 | } 139 | 140 | // OpenFile behaves like os.Open, 141 | // but uses the build context's file system interface, if any. 142 | func OpenFile(ctxt *build.Context, path string) (io.ReadCloser, error) { 143 | if ctxt.OpenFile != nil { 144 | return ctxt.OpenFile(path) 145 | } 146 | return os.Open(path) 147 | } 148 | 149 | // IsAbsPath behaves like filepath.IsAbs, 150 | // but uses the build context's file system interface, if any. 151 | func IsAbsPath(ctxt *build.Context, path string) bool { 152 | if ctxt.IsAbsPath != nil { 153 | return ctxt.IsAbsPath(path) 154 | } 155 | return filepath.IsAbs(path) 156 | } 157 | 158 | // JoinPath behaves like filepath.Join, 159 | // but uses the build context's file system interface, if any. 160 | func JoinPath(ctxt *build.Context, path ...string) string { 161 | if ctxt.JoinPath != nil { 162 | return ctxt.JoinPath(path...) 163 | } 164 | return filepath.Join(path...) 165 | } 166 | 167 | // IsDir behaves like os.Stat plus IsDir, 168 | // but uses the build context's file system interface, if any. 169 | func IsDir(ctxt *build.Context, path string) bool { 170 | if ctxt.IsDir != nil { 171 | return ctxt.IsDir(path) 172 | } 173 | fi, err := os.Stat(path) 174 | return err == nil && fi.IsDir() 175 | } 176 | 177 | // ReadDir behaves like ioutil.ReadDir, 178 | // but uses the build context's file system interface, if any. 179 | func ReadDir(ctxt *build.Context, path string) ([]os.FileInfo, error) { 180 | if ctxt.ReadDir != nil { 181 | return ctxt.ReadDir(path) 182 | } 183 | return ioutil.ReadDir(path) 184 | } 185 | 186 | // SplitPathList behaves like filepath.SplitList, 187 | // but uses the build context's file system interface, if any. 188 | func SplitPathList(ctxt *build.Context, s string) []string { 189 | if ctxt.SplitPathList != nil { 190 | return ctxt.SplitPathList(s) 191 | } 192 | return filepath.SplitList(s) 193 | } 194 | 195 | // sameFile returns true if x and y have the same basename and denote 196 | // the same file. 197 | func sameFile(x, y string) bool { 198 | if path.Clean(x) == path.Clean(y) { 199 | return true 200 | } 201 | if filepath.Base(x) == filepath.Base(y) { // (optimisation) 202 | if xi, err := os.Stat(x); err == nil { 203 | if yi, err := os.Stat(y); err == nil { 204 | return os.SameFile(xi, yi) 205 | } 206 | } 207 | } 208 | return false 209 | } 210 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/gcexportdata/gcexportdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | // Package gcexportdata provides functions for locating, reading, and 6 | // writing export data files containing type information produced by the 7 | // gc compiler. This package supports go1.7 export data format and all 8 | // later versions. 9 | // 10 | // Although it might seem convenient for this package to live alongside 11 | // go/types in the standard library, this would cause version skew 12 | // problems for developer tools that use it, since they must be able to 13 | // consume the outputs of the gc compiler both before and after a Go 14 | // update such as from Go 1.7 to Go 1.8. Because this package lives in 15 | // golang.org/x/tools, sites can update their version of this repo some 16 | // time before the Go 1.8 release and rebuild and redeploy their 17 | // developer tools, which will then be able to consume both Go 1.7 and 18 | // Go 1.8 export data files, so they will work before and after the 19 | // Go update. (See discussion at https://golang.org/issue/15651.) 20 | package gcexportdata // import "golang.org/x/tools/go/gcexportdata" 21 | 22 | import ( 23 | "bufio" 24 | "bytes" 25 | "encoding/json" 26 | "fmt" 27 | "go/token" 28 | "go/types" 29 | "io" 30 | "os/exec" 31 | 32 | "golang.org/x/tools/internal/gcimporter" 33 | ) 34 | 35 | // Find returns the name of an object (.o) or archive (.a) file 36 | // containing type information for the specified import path, 37 | // using the go command. 38 | // If no file was found, an empty filename is returned. 39 | // 40 | // A relative srcDir is interpreted relative to the current working directory. 41 | // 42 | // Find also returns the package's resolved (canonical) import path, 43 | // reflecting the effects of srcDir and vendoring on importPath. 44 | // 45 | // Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, 46 | // which is more efficient. 47 | func Find(importPath, srcDir string) (filename, path string) { 48 | cmd := exec.Command("go", "list", "-json", "-export", "--", importPath) 49 | cmd.Dir = srcDir 50 | out, err := cmd.CombinedOutput() 51 | if err != nil { 52 | return "", "" 53 | } 54 | var data struct { 55 | ImportPath string 56 | Export string 57 | } 58 | json.Unmarshal(out, &data) 59 | return data.Export, data.ImportPath 60 | } 61 | 62 | // NewReader returns a reader for the export data section of an object 63 | // (.o) or archive (.a) file read from r. The new reader may provide 64 | // additional trailing data beyond the end of the export data. 65 | func NewReader(r io.Reader) (io.Reader, error) { 66 | buf := bufio.NewReader(r) 67 | _, size, err := gcimporter.FindExportData(buf) 68 | if err != nil { 69 | return nil, err 70 | } 71 | 72 | if size >= 0 { 73 | // We were given an archive and found the __.PKGDEF in it. 74 | // This tells us the size of the export data, and we don't 75 | // need to return the entire file. 76 | return &io.LimitedReader{ 77 | R: buf, 78 | N: size, 79 | }, nil 80 | } else { 81 | // We were given an object file. As such, we don't know how large 82 | // the export data is and must return the entire file. 83 | return buf, nil 84 | } 85 | } 86 | 87 | // readAll works the same way as io.ReadAll, but avoids allocations and copies 88 | // by preallocating a byte slice of the necessary size if the size is known up 89 | // front. This is always possible when the input is an archive. In that case, 90 | // NewReader will return the known size using an io.LimitedReader. 91 | func readAll(r io.Reader) ([]byte, error) { 92 | if lr, ok := r.(*io.LimitedReader); ok { 93 | data := make([]byte, lr.N) 94 | _, err := io.ReadFull(lr, data) 95 | return data, err 96 | } 97 | return io.ReadAll(r) 98 | } 99 | 100 | // Read reads export data from in, decodes it, and returns type 101 | // information for the package. 102 | // 103 | // The package path (effectively its linker symbol prefix) is 104 | // specified by path, since unlike the package name, this information 105 | // may not be recorded in the export data. 106 | // 107 | // File position information is added to fset. 108 | // 109 | // Read may inspect and add to the imports map to ensure that references 110 | // within the export data to other packages are consistent. The caller 111 | // must ensure that imports[path] does not exist, or exists but is 112 | // incomplete (see types.Package.Complete), and Read inserts the 113 | // resulting package into this map entry. 114 | // 115 | // On return, the state of the reader is undefined. 116 | func Read(in io.Reader, fset *token.FileSet, imports map[string]*types.Package, path string) (*types.Package, error) { 117 | data, err := readAll(in) 118 | if err != nil { 119 | return nil, fmt.Errorf("reading export data for %q: %v", path, err) 120 | } 121 | 122 | if bytes.HasPrefix(data, []byte("!")) { 123 | return nil, fmt.Errorf("can't read export data for %q directly from an archive file (call gcexportdata.NewReader first to extract export data)", path) 124 | } 125 | 126 | // The indexed export format starts with an 'i'; the older 127 | // binary export format starts with a 'c', 'd', or 'v' 128 | // (from "version"). Select appropriate importer. 129 | if len(data) > 0 { 130 | switch data[0] { 131 | case 'v', 'c', 'd': // binary, till go1.10 132 | return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0]) 133 | 134 | case 'i': // indexed, till go1.19 135 | _, pkg, err := gcimporter.IImportData(fset, imports, data[1:], path) 136 | return pkg, err 137 | 138 | case 'u': // unified, from go1.20 139 | _, pkg, err := gcimporter.UImportData(fset, imports, data[1:], path) 140 | return pkg, err 141 | 142 | default: 143 | l := len(data) 144 | if l > 10 { 145 | l = 10 146 | } 147 | return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), path) 148 | } 149 | } 150 | return nil, fmt.Errorf("empty export data for %s", path) 151 | } 152 | 153 | // Write writes encoded type information for the specified package to out. 154 | // The FileSet provides file position information for named objects. 155 | func Write(out io.Writer, fset *token.FileSet, pkg *types.Package) error { 156 | if _, err := io.WriteString(out, "i"); err != nil { 157 | return err 158 | } 159 | return gcimporter.IExportData(out, fset, pkg) 160 | } 161 | 162 | // ReadBundle reads an export bundle from in, decodes it, and returns type 163 | // information for the packages. 164 | // File position information is added to fset. 165 | // 166 | // ReadBundle may inspect and add to the imports map to ensure that references 167 | // within the export bundle to other packages are consistent. 168 | // 169 | // On return, the state of the reader is undefined. 170 | // 171 | // Experimental: This API is experimental and may change in the future. 172 | func ReadBundle(in io.Reader, fset *token.FileSet, imports map[string]*types.Package) ([]*types.Package, error) { 173 | data, err := readAll(in) 174 | if err != nil { 175 | return nil, fmt.Errorf("reading export bundle: %v", err) 176 | } 177 | return gcimporter.IImportBundle(fset, imports, data) 178 | } 179 | 180 | // WriteBundle writes encoded type information for the specified packages to out. 181 | // The FileSet provides file position information for named objects. 182 | // 183 | // Experimental: This API is experimental and may change in the future. 184 | func WriteBundle(out io.Writer, fset *token.FileSet, pkgs []*types.Package) error { 185 | return gcimporter.IExportBundle(out, fset, pkgs) 186 | } 187 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/gcexportdata/importer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 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 | package gcexportdata 6 | 7 | import ( 8 | "fmt" 9 | "go/token" 10 | "go/types" 11 | "os" 12 | ) 13 | 14 | // NewImporter returns a new instance of the types.Importer interface 15 | // that reads type information from export data files written by gc. 16 | // The Importer also satisfies types.ImporterFrom. 17 | // 18 | // Export data files are located using "go build" workspace conventions 19 | // and the build.Default context. 20 | // 21 | // Use this importer instead of go/importer.For("gc", ...) to avoid the 22 | // version-skew problems described in the documentation of this package, 23 | // or to control the FileSet or access the imports map populated during 24 | // package loading. 25 | // 26 | // Deprecated: Use the higher-level API in golang.org/x/tools/go/packages, 27 | // which is more efficient. 28 | func NewImporter(fset *token.FileSet, imports map[string]*types.Package) types.ImporterFrom { 29 | return importer{fset, imports} 30 | } 31 | 32 | type importer struct { 33 | fset *token.FileSet 34 | imports map[string]*types.Package 35 | } 36 | 37 | func (imp importer) Import(importPath string) (*types.Package, error) { 38 | return imp.ImportFrom(importPath, "", 0) 39 | } 40 | 41 | func (imp importer) ImportFrom(importPath, srcDir string, mode types.ImportMode) (_ *types.Package, err error) { 42 | filename, path := Find(importPath, srcDir) 43 | if filename == "" { 44 | if importPath == "unsafe" { 45 | // Even for unsafe, call Find first in case 46 | // the package was vendored. 47 | return types.Unsafe, nil 48 | } 49 | return nil, fmt.Errorf("can't find import: %s", importPath) 50 | } 51 | 52 | if pkg, ok := imp.imports[path]; ok && pkg.Complete() { 53 | return pkg, nil // cache hit 54 | } 55 | 56 | // open file 57 | f, err := os.Open(filename) 58 | if err != nil { 59 | return nil, err 60 | } 61 | defer func() { 62 | f.Close() 63 | if err != nil { 64 | // add file name to error 65 | err = fmt.Errorf("reading export data: %s: %v", filename, err) 66 | } 67 | }() 68 | 69 | r, err := NewReader(f) 70 | if err != nil { 71 | return nil, err 72 | } 73 | 74 | return Read(r, imp.fset, imp.imports, path) 75 | } 76 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/internal/cgo/cgo_pkgconfig.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 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 | package cgo 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "go/build" 11 | "os/exec" 12 | "strings" 13 | ) 14 | 15 | // pkgConfig runs pkg-config with the specified arguments and returns the flags it prints. 16 | func pkgConfig(mode string, pkgs []string) (flags []string, err error) { 17 | cmd := exec.Command("pkg-config", append([]string{mode}, pkgs...)...) 18 | out, err := cmd.CombinedOutput() 19 | if err != nil { 20 | s := fmt.Sprintf("%s failed: %v", strings.Join(cmd.Args, " "), err) 21 | if len(out) > 0 { 22 | s = fmt.Sprintf("%s: %s", s, out) 23 | } 24 | return nil, errors.New(s) 25 | } 26 | if len(out) > 0 { 27 | flags = strings.Fields(string(out)) 28 | } 29 | return 30 | } 31 | 32 | // pkgConfigFlags calls pkg-config if needed and returns the cflags 33 | // needed to build the package. 34 | func pkgConfigFlags(p *build.Package) (cflags []string, err error) { 35 | if len(p.CgoPkgConfig) == 0 { 36 | return nil, nil 37 | } 38 | return pkgConfig("--cflags", p.CgoPkgConfig) 39 | } 40 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/internal/packagesdriver/sizes.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 | // Package packagesdriver fetches type sizes for go/packages and go/analysis. 6 | package packagesdriver 7 | 8 | import ( 9 | "context" 10 | "fmt" 11 | "strings" 12 | 13 | "golang.org/x/tools/internal/gocommand" 14 | ) 15 | 16 | func GetSizesForArgsGolist(ctx context.Context, inv gocommand.Invocation, gocmdRunner *gocommand.Runner) (string, string, error) { 17 | inv.Verb = "list" 18 | inv.Args = []string{"-f", "{{context.GOARCH}} {{context.Compiler}}", "--", "unsafe"} 19 | stdout, stderr, friendlyErr, rawErr := gocmdRunner.RunRaw(ctx, inv) 20 | var goarch, compiler string 21 | if rawErr != nil { 22 | rawErrMsg := rawErr.Error() 23 | if strings.Contains(rawErrMsg, "cannot find main module") || 24 | strings.Contains(rawErrMsg, "go.mod file not found") { 25 | // User's running outside of a module. 26 | // All bets are off. Get GOARCH and guess compiler is gc. 27 | // TODO(matloob): Is this a problem in practice? 28 | inv.Verb = "env" 29 | inv.Args = []string{"GOARCH"} 30 | envout, enverr := gocmdRunner.Run(ctx, inv) 31 | if enverr != nil { 32 | return "", "", enverr 33 | } 34 | goarch = strings.TrimSpace(envout.String()) 35 | compiler = "gc" 36 | } else if friendlyErr != nil { 37 | return "", "", friendlyErr 38 | } else { 39 | // This should be unreachable, but be defensive 40 | // in case RunRaw's error results are inconsistent. 41 | return "", "", rawErr 42 | } 43 | } else { 44 | fields := strings.Fields(stdout.String()) 45 | if len(fields) < 2 { 46 | return "", "", fmt.Errorf("could not parse GOARCH and Go compiler in format \" \":\nstdout: <<%s>>\nstderr: <<%s>>", 47 | stdout.String(), stderr.String()) 48 | } 49 | goarch = fields[0] 50 | compiler = fields[1] 51 | } 52 | return compiler, goarch, nil 53 | } 54 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/loader/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 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 | package loader 6 | 7 | import ( 8 | "go/ast" 9 | "go/build" 10 | "go/parser" 11 | "go/token" 12 | "io" 13 | "os" 14 | "strconv" 15 | "sync" 16 | 17 | "golang.org/x/tools/go/buildutil" 18 | ) 19 | 20 | // We use a counting semaphore to limit 21 | // the number of parallel I/O calls per process. 22 | var ioLimit = make(chan bool, 10) 23 | 24 | // parseFiles parses the Go source files within directory dir and 25 | // returns the ASTs of the ones that could be at least partially parsed, 26 | // along with a list of I/O and parse errors encountered. 27 | // 28 | // I/O is done via ctxt, which may specify a virtual file system. 29 | // displayPath is used to transform the filenames attached to the ASTs. 30 | func parseFiles(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, files []string, mode parser.Mode) ([]*ast.File, []error) { 31 | if displayPath == nil { 32 | displayPath = func(path string) string { return path } 33 | } 34 | var wg sync.WaitGroup 35 | n := len(files) 36 | parsed := make([]*ast.File, n) 37 | errors := make([]error, n) 38 | for i, file := range files { 39 | if !buildutil.IsAbsPath(ctxt, file) { 40 | file = buildutil.JoinPath(ctxt, dir, file) 41 | } 42 | wg.Add(1) 43 | go func(i int, file string) { 44 | ioLimit <- true // wait 45 | defer func() { 46 | wg.Done() 47 | <-ioLimit // signal 48 | }() 49 | var rd io.ReadCloser 50 | var err error 51 | if ctxt.OpenFile != nil { 52 | rd, err = ctxt.OpenFile(file) 53 | } else { 54 | rd, err = os.Open(file) 55 | } 56 | if err != nil { 57 | errors[i] = err // open failed 58 | return 59 | } 60 | 61 | // ParseFile may return both an AST and an error. 62 | parsed[i], errors[i] = parser.ParseFile(fset, displayPath(file), rd, mode) 63 | rd.Close() 64 | }(i, file) 65 | } 66 | wg.Wait() 67 | 68 | // Eliminate nils, preserving order. 69 | var o int 70 | for _, f := range parsed { 71 | if f != nil { 72 | parsed[o] = f 73 | o++ 74 | } 75 | } 76 | parsed = parsed[:o] 77 | 78 | o = 0 79 | for _, err := range errors { 80 | if err != nil { 81 | errors[o] = err 82 | o++ 83 | } 84 | } 85 | errors = errors[:o] 86 | 87 | return parsed, errors 88 | } 89 | 90 | // scanImports returns the set of all import paths from all 91 | // import specs in the specified files. 92 | func scanImports(files []*ast.File) map[string]bool { 93 | imports := make(map[string]bool) 94 | for _, f := range files { 95 | for _, decl := range f.Decls { 96 | if decl, ok := decl.(*ast.GenDecl); ok && decl.Tok == token.IMPORT { 97 | for _, spec := range decl.Specs { 98 | spec := spec.(*ast.ImportSpec) 99 | 100 | // NB: do not assume the program is well-formed! 101 | path, err := strconv.Unquote(spec.Path.Value) 102 | if err != nil { 103 | continue // quietly ignore the error 104 | } 105 | if path == "C" { 106 | continue // skip pseudopackage 107 | } 108 | imports[path] = true 109 | } 110 | } 111 | } 112 | } 113 | return imports 114 | } 115 | 116 | // ---------- Internal helpers ---------- 117 | 118 | // TODO(adonovan): make this a method: func (*token.File) Contains(token.Pos) 119 | func tokenFileContainsPos(f *token.File, pos token.Pos) bool { 120 | p := int(pos) 121 | base := f.Base() 122 | return base <= p && p < base+f.Size() 123 | } 124 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/packages/external.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 enables an external tool to intercept package requests. 6 | // If the tool is present then its results are used in preference to 7 | // the go list command. 8 | 9 | package packages 10 | 11 | import ( 12 | "bytes" 13 | "encoding/json" 14 | "fmt" 15 | "os" 16 | "os/exec" 17 | "strings" 18 | ) 19 | 20 | // The Driver Protocol 21 | // 22 | // The driver, given the inputs to a call to Load, returns metadata about the packages specified. 23 | // This allows for different build systems to support go/packages by telling go/packages how the 24 | // packages' source is organized. 25 | // The driver is a binary, either specified by the GOPACKAGESDRIVER environment variable or in 26 | // the path as gopackagesdriver. It's given the inputs to load in its argv. See the package 27 | // documentation in doc.go for the full description of the patterns that need to be supported. 28 | // A driver receives as a JSON-serialized driverRequest struct in standard input and will 29 | // produce a JSON-serialized driverResponse (see definition in packages.go) in its standard output. 30 | 31 | // driverRequest is used to provide the portion of Load's Config that is needed by a driver. 32 | type driverRequest struct { 33 | Mode LoadMode `json:"mode"` 34 | // Env specifies the environment the underlying build system should be run in. 35 | Env []string `json:"env"` 36 | // BuildFlags are flags that should be passed to the underlying build system. 37 | BuildFlags []string `json:"build_flags"` 38 | // Tests specifies whether the patterns should also return test packages. 39 | Tests bool `json:"tests"` 40 | // Overlay maps file paths (relative to the driver's working directory) to the byte contents 41 | // of overlay files. 42 | Overlay map[string][]byte `json:"overlay"` 43 | } 44 | 45 | // findExternalDriver returns the file path of a tool that supplies 46 | // the build system package structure, or "" if not found." 47 | // If GOPACKAGESDRIVER is set in the environment findExternalTool returns its 48 | // value, otherwise it searches for a binary named gopackagesdriver on the PATH. 49 | func findExternalDriver(cfg *Config) driver { 50 | const toolPrefix = "GOPACKAGESDRIVER=" 51 | tool := "" 52 | for _, env := range cfg.Env { 53 | if val := strings.TrimPrefix(env, toolPrefix); val != env { 54 | tool = val 55 | } 56 | } 57 | if tool != "" && tool == "off" { 58 | return nil 59 | } 60 | if tool == "" { 61 | var err error 62 | tool, err = exec.LookPath("gopackagesdriver") 63 | if err != nil { 64 | return nil 65 | } 66 | } 67 | return func(cfg *Config, words ...string) (*driverResponse, error) { 68 | req, err := json.Marshal(driverRequest{ 69 | Mode: cfg.Mode, 70 | Env: cfg.Env, 71 | BuildFlags: cfg.BuildFlags, 72 | Tests: cfg.Tests, 73 | Overlay: cfg.Overlay, 74 | }) 75 | if err != nil { 76 | return nil, fmt.Errorf("failed to encode message to driver tool: %v", err) 77 | } 78 | 79 | buf := new(bytes.Buffer) 80 | stderr := new(bytes.Buffer) 81 | cmd := exec.CommandContext(cfg.Context, tool, words...) 82 | cmd.Dir = cfg.Dir 83 | cmd.Env = cfg.Env 84 | cmd.Stdin = bytes.NewReader(req) 85 | cmd.Stdout = buf 86 | cmd.Stderr = stderr 87 | 88 | if err := cmd.Run(); err != nil { 89 | return nil, fmt.Errorf("%v: %v: %s", tool, err, cmd.Stderr) 90 | } 91 | if len(stderr.Bytes()) != 0 && os.Getenv("GOPACKAGESPRINTDRIVERERRORS") != "" { 92 | fmt.Fprintf(os.Stderr, "%s stderr: <<%s>>\n", cmdDebugStr(cmd), stderr) 93 | } 94 | 95 | var response driverResponse 96 | if err := json.Unmarshal(buf.Bytes(), &response); err != nil { 97 | return nil, err 98 | } 99 | return &response, nil 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/packages/golist_overlay.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 | package packages 6 | 7 | import ( 8 | "encoding/json" 9 | "path/filepath" 10 | 11 | "golang.org/x/tools/internal/gocommand" 12 | ) 13 | 14 | // determineRootDirs returns a mapping from absolute directories that could 15 | // contain code to their corresponding import path prefixes. 16 | func (state *golistState) determineRootDirs() (map[string]string, error) { 17 | env, err := state.getEnv() 18 | if err != nil { 19 | return nil, err 20 | } 21 | if env["GOMOD"] != "" { 22 | state.rootsOnce.Do(func() { 23 | state.rootDirs, state.rootDirsError = state.determineRootDirsModules() 24 | }) 25 | } else { 26 | state.rootsOnce.Do(func() { 27 | state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH() 28 | }) 29 | } 30 | return state.rootDirs, state.rootDirsError 31 | } 32 | 33 | func (state *golistState) determineRootDirsModules() (map[string]string, error) { 34 | // List all of the modules--the first will be the directory for the main 35 | // module. Any replaced modules will also need to be treated as roots. 36 | // Editing files in the module cache isn't a great idea, so we don't 37 | // plan to ever support that. 38 | out, err := state.invokeGo("list", "-m", "-json", "all") 39 | if err != nil { 40 | // 'go list all' will fail if we're outside of a module and 41 | // GO111MODULE=on. Try falling back without 'all'. 42 | var innerErr error 43 | out, innerErr = state.invokeGo("list", "-m", "-json") 44 | if innerErr != nil { 45 | return nil, err 46 | } 47 | } 48 | roots := map[string]string{} 49 | modules := map[string]string{} 50 | var i int 51 | for dec := json.NewDecoder(out); dec.More(); { 52 | mod := new(gocommand.ModuleJSON) 53 | if err := dec.Decode(mod); err != nil { 54 | return nil, err 55 | } 56 | if mod.Dir != "" && mod.Path != "" { 57 | // This is a valid module; add it to the map. 58 | absDir, err := filepath.Abs(mod.Dir) 59 | if err != nil { 60 | return nil, err 61 | } 62 | modules[absDir] = mod.Path 63 | // The first result is the main module. 64 | if i == 0 || mod.Replace != nil && mod.Replace.Path != "" { 65 | roots[absDir] = mod.Path 66 | } 67 | } 68 | i++ 69 | } 70 | return roots, nil 71 | } 72 | 73 | func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) { 74 | m := map[string]string{} 75 | for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) { 76 | absDir, err := filepath.Abs(dir) 77 | if err != nil { 78 | return nil, err 79 | } 80 | m[filepath.Join(absDir, "src")] = "" 81 | } 82 | return m, nil 83 | } 84 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/packages/loadmode_string.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | package packages 6 | 7 | import ( 8 | "fmt" 9 | "strings" 10 | ) 11 | 12 | var allModes = []LoadMode{ 13 | NeedName, 14 | NeedFiles, 15 | NeedCompiledGoFiles, 16 | NeedImports, 17 | NeedDeps, 18 | NeedExportFile, 19 | NeedTypes, 20 | NeedSyntax, 21 | NeedTypesInfo, 22 | NeedTypesSizes, 23 | } 24 | 25 | var modeStrings = []string{ 26 | "NeedName", 27 | "NeedFiles", 28 | "NeedCompiledGoFiles", 29 | "NeedImports", 30 | "NeedDeps", 31 | "NeedExportFile", 32 | "NeedTypes", 33 | "NeedSyntax", 34 | "NeedTypesInfo", 35 | "NeedTypesSizes", 36 | } 37 | 38 | func (mod LoadMode) String() string { 39 | m := mod 40 | if m == 0 { 41 | return "LoadMode(0)" 42 | } 43 | var out []string 44 | for i, x := range allModes { 45 | if x > m { 46 | break 47 | } 48 | if (m & x) != 0 { 49 | out = append(out, modeStrings[i]) 50 | m = m ^ x 51 | } 52 | } 53 | if m != 0 { 54 | out = append(out, "Unknown") 55 | } 56 | return fmt.Sprintf("LoadMode(%s)", strings.Join(out, "|")) 57 | } 58 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/go/packages/visit.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 | package packages 6 | 7 | import ( 8 | "fmt" 9 | "os" 10 | "sort" 11 | ) 12 | 13 | // Visit visits all the packages in the import graph whose roots are 14 | // pkgs, calling the optional pre function the first time each package 15 | // is encountered (preorder), and the optional post function after a 16 | // package's dependencies have been visited (postorder). 17 | // The boolean result of pre(pkg) determines whether 18 | // the imports of package pkg are visited. 19 | func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) { 20 | seen := make(map[*Package]bool) 21 | var visit func(*Package) 22 | visit = func(pkg *Package) { 23 | if !seen[pkg] { 24 | seen[pkg] = true 25 | 26 | if pre == nil || pre(pkg) { 27 | paths := make([]string, 0, len(pkg.Imports)) 28 | for path := range pkg.Imports { 29 | paths = append(paths, path) 30 | } 31 | sort.Strings(paths) // Imports is a map, this makes visit stable 32 | for _, path := range paths { 33 | visit(pkg.Imports[path]) 34 | } 35 | } 36 | 37 | if post != nil { 38 | post(pkg) 39 | } 40 | } 41 | } 42 | for _, pkg := range pkgs { 43 | visit(pkg) 44 | } 45 | } 46 | 47 | // PrintErrors prints to os.Stderr the accumulated errors of all 48 | // packages in the import graph rooted at pkgs, dependencies first. 49 | // PrintErrors returns the number of errors printed. 50 | func PrintErrors(pkgs []*Package) int { 51 | var n int 52 | Visit(pkgs, nil, func(pkg *Package) { 53 | for _, err := range pkg.Errors { 54 | fmt.Fprintln(os.Stderr, err) 55 | n++ 56 | } 57 | }) 58 | return n 59 | } 60 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/event/core/event.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | // Package core provides support for event based telemetry. 6 | package core 7 | 8 | import ( 9 | "fmt" 10 | "time" 11 | 12 | "golang.org/x/tools/internal/event/label" 13 | ) 14 | 15 | // Event holds the information about an event of note that occurred. 16 | type Event struct { 17 | at time.Time 18 | 19 | // As events are often on the stack, storing the first few labels directly 20 | // in the event can avoid an allocation at all for the very common cases of 21 | // simple events. 22 | // The length needs to be large enough to cope with the majority of events 23 | // but no so large as to cause undue stack pressure. 24 | // A log message with two values will use 3 labels (one for each value and 25 | // one for the message itself). 26 | 27 | static [3]label.Label // inline storage for the first few labels 28 | dynamic []label.Label // dynamically sized storage for remaining labels 29 | } 30 | 31 | // eventLabelMap implements label.Map for a the labels of an Event. 32 | type eventLabelMap struct { 33 | event Event 34 | } 35 | 36 | func (ev Event) At() time.Time { return ev.at } 37 | 38 | func (ev Event) Format(f fmt.State, r rune) { 39 | if !ev.at.IsZero() { 40 | fmt.Fprint(f, ev.at.Format("2006/01/02 15:04:05 ")) 41 | } 42 | for index := 0; ev.Valid(index); index++ { 43 | if l := ev.Label(index); l.Valid() { 44 | fmt.Fprintf(f, "\n\t%v", l) 45 | } 46 | } 47 | } 48 | 49 | func (ev Event) Valid(index int) bool { 50 | return index >= 0 && index < len(ev.static)+len(ev.dynamic) 51 | } 52 | 53 | func (ev Event) Label(index int) label.Label { 54 | if index < len(ev.static) { 55 | return ev.static[index] 56 | } 57 | return ev.dynamic[index-len(ev.static)] 58 | } 59 | 60 | func (ev Event) Find(key label.Key) label.Label { 61 | for _, l := range ev.static { 62 | if l.Key() == key { 63 | return l 64 | } 65 | } 66 | for _, l := range ev.dynamic { 67 | if l.Key() == key { 68 | return l 69 | } 70 | } 71 | return label.Label{} 72 | } 73 | 74 | func MakeEvent(static [3]label.Label, labels []label.Label) Event { 75 | return Event{ 76 | static: static, 77 | dynamic: labels, 78 | } 79 | } 80 | 81 | // CloneEvent event returns a copy of the event with the time adjusted to at. 82 | func CloneEvent(ev Event, at time.Time) Event { 83 | ev.at = at 84 | return ev 85 | } 86 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/event/core/export.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | package core 6 | 7 | import ( 8 | "context" 9 | "sync/atomic" 10 | "time" 11 | "unsafe" 12 | 13 | "golang.org/x/tools/internal/event/label" 14 | ) 15 | 16 | // Exporter is a function that handles events. 17 | // It may return a modified context and event. 18 | type Exporter func(context.Context, Event, label.Map) context.Context 19 | 20 | var ( 21 | exporter unsafe.Pointer 22 | ) 23 | 24 | // SetExporter sets the global exporter function that handles all events. 25 | // The exporter is called synchronously from the event call site, so it should 26 | // return quickly so as not to hold up user code. 27 | func SetExporter(e Exporter) { 28 | p := unsafe.Pointer(&e) 29 | if e == nil { 30 | // &e is always valid, and so p is always valid, but for the early abort 31 | // of ProcessEvent to be efficient it needs to make the nil check on the 32 | // pointer without having to dereference it, so we make the nil function 33 | // also a nil pointer 34 | p = nil 35 | } 36 | atomic.StorePointer(&exporter, p) 37 | } 38 | 39 | // deliver is called to deliver an event to the supplied exporter. 40 | // it will fill in the time. 41 | func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context { 42 | // add the current time to the event 43 | ev.at = time.Now() 44 | // hand the event off to the current exporter 45 | return exporter(ctx, ev, ev) 46 | } 47 | 48 | // Export is called to deliver an event to the global exporter if set. 49 | func Export(ctx context.Context, ev Event) context.Context { 50 | // get the global exporter and abort early if there is not one 51 | exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) 52 | if exporterPtr == nil { 53 | return ctx 54 | } 55 | return deliver(ctx, *exporterPtr, ev) 56 | } 57 | 58 | // ExportPair is called to deliver a start event to the supplied exporter. 59 | // It also returns a function that will deliver the end event to the same 60 | // exporter. 61 | // It will fill in the time. 62 | func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) { 63 | // get the global exporter and abort early if there is not one 64 | exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter)) 65 | if exporterPtr == nil { 66 | return ctx, func() {} 67 | } 68 | ctx = deliver(ctx, *exporterPtr, begin) 69 | return ctx, func() { deliver(ctx, *exporterPtr, end) } 70 | } 71 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/event/core/fast.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | package core 6 | 7 | import ( 8 | "context" 9 | 10 | "golang.org/x/tools/internal/event/keys" 11 | "golang.org/x/tools/internal/event/label" 12 | ) 13 | 14 | // Log1 takes a message and one label delivers a log event to the exporter. 15 | // It is a customized version of Print that is faster and does no allocation. 16 | func Log1(ctx context.Context, message string, t1 label.Label) { 17 | Export(ctx, MakeEvent([3]label.Label{ 18 | keys.Msg.Of(message), 19 | t1, 20 | }, nil)) 21 | } 22 | 23 | // Log2 takes a message and two labels and delivers a log event to the exporter. 24 | // It is a customized version of Print that is faster and does no allocation. 25 | func Log2(ctx context.Context, message string, t1 label.Label, t2 label.Label) { 26 | Export(ctx, MakeEvent([3]label.Label{ 27 | keys.Msg.Of(message), 28 | t1, 29 | t2, 30 | }, nil)) 31 | } 32 | 33 | // Metric1 sends a label event to the exporter with the supplied labels. 34 | func Metric1(ctx context.Context, t1 label.Label) context.Context { 35 | return Export(ctx, MakeEvent([3]label.Label{ 36 | keys.Metric.New(), 37 | t1, 38 | }, nil)) 39 | } 40 | 41 | // Metric2 sends a label event to the exporter with the supplied labels. 42 | func Metric2(ctx context.Context, t1, t2 label.Label) context.Context { 43 | return Export(ctx, MakeEvent([3]label.Label{ 44 | keys.Metric.New(), 45 | t1, 46 | t2, 47 | }, nil)) 48 | } 49 | 50 | // Start1 sends a span start event with the supplied label list to the exporter. 51 | // It also returns a function that will end the span, which should normally be 52 | // deferred. 53 | func Start1(ctx context.Context, name string, t1 label.Label) (context.Context, func()) { 54 | return ExportPair(ctx, 55 | MakeEvent([3]label.Label{ 56 | keys.Start.Of(name), 57 | t1, 58 | }, nil), 59 | MakeEvent([3]label.Label{ 60 | keys.End.New(), 61 | }, nil)) 62 | } 63 | 64 | // Start2 sends a span start event with the supplied label list to the exporter. 65 | // It also returns a function that will end the span, which should normally be 66 | // deferred. 67 | func Start2(ctx context.Context, name string, t1, t2 label.Label) (context.Context, func()) { 68 | return ExportPair(ctx, 69 | MakeEvent([3]label.Label{ 70 | keys.Start.Of(name), 71 | t1, 72 | t2, 73 | }, nil), 74 | MakeEvent([3]label.Label{ 75 | keys.End.New(), 76 | }, nil)) 77 | } 78 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/event/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | // Package event provides a set of packages that cover the main 6 | // concepts of telemetry in an implementation agnostic way. 7 | package event 8 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/event/event.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | package event 6 | 7 | import ( 8 | "context" 9 | 10 | "golang.org/x/tools/internal/event/core" 11 | "golang.org/x/tools/internal/event/keys" 12 | "golang.org/x/tools/internal/event/label" 13 | ) 14 | 15 | // Exporter is a function that handles events. 16 | // It may return a modified context and event. 17 | type Exporter func(context.Context, core.Event, label.Map) context.Context 18 | 19 | // SetExporter sets the global exporter function that handles all events. 20 | // The exporter is called synchronously from the event call site, so it should 21 | // return quickly so as not to hold up user code. 22 | func SetExporter(e Exporter) { 23 | core.SetExporter(core.Exporter(e)) 24 | } 25 | 26 | // Log takes a message and a label list and combines them into a single event 27 | // before delivering them to the exporter. 28 | func Log(ctx context.Context, message string, labels ...label.Label) { 29 | core.Export(ctx, core.MakeEvent([3]label.Label{ 30 | keys.Msg.Of(message), 31 | }, labels)) 32 | } 33 | 34 | // IsLog returns true if the event was built by the Log function. 35 | // It is intended to be used in exporters to identify the semantics of the 36 | // event when deciding what to do with it. 37 | func IsLog(ev core.Event) bool { 38 | return ev.Label(0).Key() == keys.Msg 39 | } 40 | 41 | // Error takes a message and a label list and combines them into a single event 42 | // before delivering them to the exporter. It captures the error in the 43 | // delivered event. 44 | func Error(ctx context.Context, message string, err error, labels ...label.Label) { 45 | core.Export(ctx, core.MakeEvent([3]label.Label{ 46 | keys.Msg.Of(message), 47 | keys.Err.Of(err), 48 | }, labels)) 49 | } 50 | 51 | // IsError returns true if the event was built by the Error function. 52 | // It is intended to be used in exporters to identify the semantics of the 53 | // event when deciding what to do with it. 54 | func IsError(ev core.Event) bool { 55 | return ev.Label(0).Key() == keys.Msg && 56 | ev.Label(1).Key() == keys.Err 57 | } 58 | 59 | // Metric sends a label event to the exporter with the supplied labels. 60 | func Metric(ctx context.Context, labels ...label.Label) { 61 | core.Export(ctx, core.MakeEvent([3]label.Label{ 62 | keys.Metric.New(), 63 | }, labels)) 64 | } 65 | 66 | // IsMetric returns true if the event was built by the Metric function. 67 | // It is intended to be used in exporters to identify the semantics of the 68 | // event when deciding what to do with it. 69 | func IsMetric(ev core.Event) bool { 70 | return ev.Label(0).Key() == keys.Metric 71 | } 72 | 73 | // Label sends a label event to the exporter with the supplied labels. 74 | func Label(ctx context.Context, labels ...label.Label) context.Context { 75 | return core.Export(ctx, core.MakeEvent([3]label.Label{ 76 | keys.Label.New(), 77 | }, labels)) 78 | } 79 | 80 | // IsLabel returns true if the event was built by the Label function. 81 | // It is intended to be used in exporters to identify the semantics of the 82 | // event when deciding what to do with it. 83 | func IsLabel(ev core.Event) bool { 84 | return ev.Label(0).Key() == keys.Label 85 | } 86 | 87 | // Start sends a span start event with the supplied label list to the exporter. 88 | // It also returns a function that will end the span, which should normally be 89 | // deferred. 90 | func Start(ctx context.Context, name string, labels ...label.Label) (context.Context, func()) { 91 | return core.ExportPair(ctx, 92 | core.MakeEvent([3]label.Label{ 93 | keys.Start.Of(name), 94 | }, labels), 95 | core.MakeEvent([3]label.Label{ 96 | keys.End.New(), 97 | }, nil)) 98 | } 99 | 100 | // IsStart returns true if the event was built by the Start function. 101 | // It is intended to be used in exporters to identify the semantics of the 102 | // event when deciding what to do with it. 103 | func IsStart(ev core.Event) bool { 104 | return ev.Label(0).Key() == keys.Start 105 | } 106 | 107 | // IsEnd returns true if the event was built by the End function. 108 | // It is intended to be used in exporters to identify the semantics of the 109 | // event when deciding what to do with it. 110 | func IsEnd(ev core.Event) bool { 111 | return ev.Label(0).Key() == keys.End 112 | } 113 | 114 | // Detach returns a context without an associated span. 115 | // This allows the creation of spans that are not children of the current span. 116 | func Detach(ctx context.Context) context.Context { 117 | return core.Export(ctx, core.MakeEvent([3]label.Label{ 118 | keys.Detach.New(), 119 | }, nil)) 120 | } 121 | 122 | // IsDetach returns true if the event was built by the Detach function. 123 | // It is intended to be used in exporters to identify the semantics of the 124 | // event when deciding what to do with it. 125 | func IsDetach(ev core.Event) bool { 126 | return ev.Label(0).Key() == keys.Detach 127 | } 128 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/event/keys/standard.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 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 | package keys 6 | 7 | var ( 8 | // Msg is a key used to add message strings to label lists. 9 | Msg = NewString("message", "a readable message") 10 | // Label is a key used to indicate an event adds labels to the context. 11 | Label = NewTag("label", "a label context marker") 12 | // Start is used for things like traces that have a name. 13 | Start = NewString("start", "span start") 14 | // Metric is a key used to indicate an event records metrics. 15 | End = NewTag("end", "a span end marker") 16 | // Metric is a key used to indicate an event records metrics. 17 | Detach = NewTag("detach", "a span detach marker") 18 | // Err is a key used to add error values to label lists. 19 | Err = NewError("error", "an error that occurred") 20 | // Metric is a key used to indicate an event records metrics. 21 | Metric = NewTag("metric", "a metric event marker") 22 | ) 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/event/keys/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 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 | package keys 6 | 7 | import ( 8 | "sort" 9 | "strings" 10 | ) 11 | 12 | // Join returns a canonical join of the keys in S: 13 | // a sorted comma-separated string list. 14 | func Join[S ~[]T, T ~string](s S) string { 15 | strs := make([]string, 0, len(s)) 16 | for _, v := range s { 17 | strs = append(strs, string(v)) 18 | } 19 | sort.Strings(strs) 20 | return strings.Join(strs, ",") 21 | } 22 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/event/label/label.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | package label 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | "reflect" 11 | "unsafe" 12 | ) 13 | 14 | // Key is used as the identity of a Label. 15 | // Keys are intended to be compared by pointer only, the name should be unique 16 | // for communicating with external systems, but it is not required or enforced. 17 | type Key interface { 18 | // Name returns the key name. 19 | Name() string 20 | // Description returns a string that can be used to describe the value. 21 | Description() string 22 | 23 | // Format is used in formatting to append the value of the label to the 24 | // supplied buffer. 25 | // The formatter may use the supplied buf as a scratch area to avoid 26 | // allocations. 27 | Format(w io.Writer, buf []byte, l Label) 28 | } 29 | 30 | // Label holds a key and value pair. 31 | // It is normally used when passing around lists of labels. 32 | type Label struct { 33 | key Key 34 | packed uint64 35 | untyped interface{} 36 | } 37 | 38 | // Map is the interface to a collection of Labels indexed by key. 39 | type Map interface { 40 | // Find returns the label that matches the supplied key. 41 | Find(key Key) Label 42 | } 43 | 44 | // List is the interface to something that provides an iterable 45 | // list of labels. 46 | // Iteration should start from 0 and continue until Valid returns false. 47 | type List interface { 48 | // Valid returns true if the index is within range for the list. 49 | // It does not imply the label at that index will itself be valid. 50 | Valid(index int) bool 51 | // Label returns the label at the given index. 52 | Label(index int) Label 53 | } 54 | 55 | // list implements LabelList for a list of Labels. 56 | type list struct { 57 | labels []Label 58 | } 59 | 60 | // filter wraps a LabelList filtering out specific labels. 61 | type filter struct { 62 | keys []Key 63 | underlying List 64 | } 65 | 66 | // listMap implements LabelMap for a simple list of labels. 67 | type listMap struct { 68 | labels []Label 69 | } 70 | 71 | // mapChain implements LabelMap for a list of underlying LabelMap. 72 | type mapChain struct { 73 | maps []Map 74 | } 75 | 76 | // OfValue creates a new label from the key and value. 77 | // This method is for implementing new key types, label creation should 78 | // normally be done with the Of method of the key. 79 | func OfValue(k Key, value interface{}) Label { return Label{key: k, untyped: value} } 80 | 81 | // UnpackValue assumes the label was built using LabelOfValue and returns the value 82 | // that was passed to that constructor. 83 | // This method is for implementing new key types, for type safety normal 84 | // access should be done with the From method of the key. 85 | func (t Label) UnpackValue() interface{} { return t.untyped } 86 | 87 | // Of64 creates a new label from a key and a uint64. This is often 88 | // used for non uint64 values that can be packed into a uint64. 89 | // This method is for implementing new key types, label creation should 90 | // normally be done with the Of method of the key. 91 | func Of64(k Key, v uint64) Label { return Label{key: k, packed: v} } 92 | 93 | // Unpack64 assumes the label was built using LabelOf64 and returns the value that 94 | // was passed to that constructor. 95 | // This method is for implementing new key types, for type safety normal 96 | // access should be done with the From method of the key. 97 | func (t Label) Unpack64() uint64 { return t.packed } 98 | 99 | type stringptr unsafe.Pointer 100 | 101 | // OfString creates a new label from a key and a string. 102 | // This method is for implementing new key types, label creation should 103 | // normally be done with the Of method of the key. 104 | func OfString(k Key, v string) Label { 105 | hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) 106 | return Label{ 107 | key: k, 108 | packed: uint64(hdr.Len), 109 | untyped: stringptr(hdr.Data), 110 | } 111 | } 112 | 113 | // UnpackString assumes the label was built using LabelOfString and returns the 114 | // value that was passed to that constructor. 115 | // This method is for implementing new key types, for type safety normal 116 | // access should be done with the From method of the key. 117 | func (t Label) UnpackString() string { 118 | var v string 119 | hdr := (*reflect.StringHeader)(unsafe.Pointer(&v)) 120 | hdr.Data = uintptr(t.untyped.(stringptr)) 121 | hdr.Len = int(t.packed) 122 | return v 123 | } 124 | 125 | // Valid returns true if the Label is a valid one (it has a key). 126 | func (t Label) Valid() bool { return t.key != nil } 127 | 128 | // Key returns the key of this Label. 129 | func (t Label) Key() Key { return t.key } 130 | 131 | // Format is used for debug printing of labels. 132 | func (t Label) Format(f fmt.State, r rune) { 133 | if !t.Valid() { 134 | io.WriteString(f, `nil`) 135 | return 136 | } 137 | io.WriteString(f, t.Key().Name()) 138 | io.WriteString(f, "=") 139 | var buf [128]byte 140 | t.Key().Format(f, buf[:0], t) 141 | } 142 | 143 | func (l *list) Valid(index int) bool { 144 | return index >= 0 && index < len(l.labels) 145 | } 146 | 147 | func (l *list) Label(index int) Label { 148 | return l.labels[index] 149 | } 150 | 151 | func (f *filter) Valid(index int) bool { 152 | return f.underlying.Valid(index) 153 | } 154 | 155 | func (f *filter) Label(index int) Label { 156 | l := f.underlying.Label(index) 157 | for _, f := range f.keys { 158 | if l.Key() == f { 159 | return Label{} 160 | } 161 | } 162 | return l 163 | } 164 | 165 | func (lm listMap) Find(key Key) Label { 166 | for _, l := range lm.labels { 167 | if l.Key() == key { 168 | return l 169 | } 170 | } 171 | return Label{} 172 | } 173 | 174 | func (c mapChain) Find(key Key) Label { 175 | for _, src := range c.maps { 176 | l := src.Find(key) 177 | if l.Valid() { 178 | return l 179 | } 180 | } 181 | return Label{} 182 | } 183 | 184 | var emptyList = &list{} 185 | 186 | func NewList(labels ...Label) List { 187 | if len(labels) == 0 { 188 | return emptyList 189 | } 190 | return &list{labels: labels} 191 | } 192 | 193 | func Filter(l List, keys ...Key) List { 194 | if len(keys) == 0 { 195 | return l 196 | } 197 | return &filter{keys: keys, underlying: l} 198 | } 199 | 200 | func NewMap(labels ...Label) Map { 201 | return listMap{labels: labels} 202 | } 203 | 204 | func MergeMaps(srcs ...Map) Map { 205 | var nonNil []Map 206 | for _, src := range srcs { 207 | if src != nil { 208 | nonNil = append(nonNil, src) 209 | } 210 | } 211 | if len(nonNil) == 1 { 212 | return nonNil[0] 213 | } 214 | return mapChain{maps: nonNil} 215 | } 216 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/event/tag/tag.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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 | // Package tag provides the labels used for telemetry throughout gopls. 6 | package tag 7 | 8 | import ( 9 | "golang.org/x/tools/internal/event/keys" 10 | ) 11 | 12 | var ( 13 | // create the label keys we use 14 | Method = keys.NewString("method", "") 15 | StatusCode = keys.NewString("status.code", "") 16 | StatusMessage = keys.NewString("status.message", "") 17 | RPCID = keys.NewString("id", "") 18 | RPCDirection = keys.NewString("direction", "") 19 | File = keys.NewString("file", "") 20 | Directory = keys.New("directory", "") 21 | URI = keys.New("URI", "") 22 | Package = keys.NewString("package", "") // sorted comma-separated list of Package IDs 23 | PackagePath = keys.NewString("package_path", "") 24 | Query = keys.New("query", "") 25 | Snapshot = keys.NewUInt64("snapshot", "") 26 | Operation = keys.NewString("operation", "") 27 | 28 | Position = keys.New("position", "") 29 | Category = keys.NewString("category", "") 30 | PackageCount = keys.NewInt("packages", "") 31 | Files = keys.New("files", "") 32 | Port = keys.NewInt("port", "") 33 | Type = keys.New("type", "") 34 | HoverKind = keys.NewString("hoverkind", "") 35 | 36 | NewServer = keys.NewString("new_server", "A new server was added") 37 | EndServer = keys.NewString("end_server", "A server was shut down") 38 | 39 | ServerID = keys.NewString("server", "The server ID an event is related to") 40 | Logfile = keys.NewString("logfile", "") 41 | DebugAddress = keys.NewString("debug_address", "") 42 | GoplsPath = keys.NewString("gopls_path", "") 43 | ClientID = keys.NewString("client_id", "") 44 | 45 | Level = keys.NewInt("level", "The logging level") 46 | ) 47 | 48 | var ( 49 | // create the stats we measure 50 | Started = keys.NewInt64("started", "Count of started RPCs.") 51 | ReceivedBytes = keys.NewInt64("received_bytes", "Bytes received.") //, unit.Bytes) 52 | SentBytes = keys.NewInt64("sent_bytes", "Bytes sent.") //, unit.Bytes) 53 | Latency = keys.NewFloat64("latency_ms", "Elapsed time in milliseconds") //, unit.Milliseconds) 54 | ) 55 | 56 | const ( 57 | Inbound = "in" 58 | Outbound = "out" 59 | ) 60 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gcimporter/bimport.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 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 contains the remaining vestiges of 6 | // $GOROOT/src/go/internal/gcimporter/bimport.go. 7 | 8 | package gcimporter 9 | 10 | import ( 11 | "fmt" 12 | "go/token" 13 | "go/types" 14 | "sync" 15 | ) 16 | 17 | func errorf(format string, args ...interface{}) { 18 | panic(fmt.Sprintf(format, args...)) 19 | } 20 | 21 | const deltaNewFile = -64 // see cmd/compile/internal/gc/bexport.go 22 | 23 | // Synthesize a token.Pos 24 | type fakeFileSet struct { 25 | fset *token.FileSet 26 | files map[string]*fileInfo 27 | } 28 | 29 | type fileInfo struct { 30 | file *token.File 31 | lastline int 32 | } 33 | 34 | const maxlines = 64 * 1024 35 | 36 | func (s *fakeFileSet) pos(file string, line, column int) token.Pos { 37 | // TODO(mdempsky): Make use of column. 38 | 39 | // Since we don't know the set of needed file positions, we reserve maxlines 40 | // positions per file. We delay calling token.File.SetLines until all 41 | // positions have been calculated (by way of fakeFileSet.setLines), so that 42 | // we can avoid setting unnecessary lines. See also golang/go#46586. 43 | f := s.files[file] 44 | if f == nil { 45 | f = &fileInfo{file: s.fset.AddFile(file, -1, maxlines)} 46 | s.files[file] = f 47 | } 48 | if line > maxlines { 49 | line = 1 50 | } 51 | if line > f.lastline { 52 | f.lastline = line 53 | } 54 | 55 | // Return a fake position assuming that f.file consists only of newlines. 56 | return token.Pos(f.file.Base() + line - 1) 57 | } 58 | 59 | func (s *fakeFileSet) setLines() { 60 | fakeLinesOnce.Do(func() { 61 | fakeLines = make([]int, maxlines) 62 | for i := range fakeLines { 63 | fakeLines[i] = i 64 | } 65 | }) 66 | for _, f := range s.files { 67 | f.file.SetLines(fakeLines[:f.lastline]) 68 | } 69 | } 70 | 71 | var ( 72 | fakeLines []int 73 | fakeLinesOnce sync.Once 74 | ) 75 | 76 | func chanDir(d int) types.ChanDir { 77 | // tag values must match the constants in cmd/compile/internal/gc/go.go 78 | switch d { 79 | case 1 /* Crecv */ : 80 | return types.RecvOnly 81 | case 2 /* Csend */ : 82 | return types.SendOnly 83 | case 3 /* Cboth */ : 84 | return types.SendRecv 85 | default: 86 | errorf("unexpected channel dir %d", d) 87 | return 0 88 | } 89 | } 90 | 91 | var predeclOnce sync.Once 92 | var predecl []types.Type // initialized lazily 93 | 94 | func predeclared() []types.Type { 95 | predeclOnce.Do(func() { 96 | // initialize lazily to be sure that all 97 | // elements have been initialized before 98 | predecl = []types.Type{ // basic types 99 | types.Typ[types.Bool], 100 | types.Typ[types.Int], 101 | types.Typ[types.Int8], 102 | types.Typ[types.Int16], 103 | types.Typ[types.Int32], 104 | types.Typ[types.Int64], 105 | types.Typ[types.Uint], 106 | types.Typ[types.Uint8], 107 | types.Typ[types.Uint16], 108 | types.Typ[types.Uint32], 109 | types.Typ[types.Uint64], 110 | types.Typ[types.Uintptr], 111 | types.Typ[types.Float32], 112 | types.Typ[types.Float64], 113 | types.Typ[types.Complex64], 114 | types.Typ[types.Complex128], 115 | types.Typ[types.String], 116 | 117 | // basic type aliases 118 | types.Universe.Lookup("byte").Type(), 119 | types.Universe.Lookup("rune").Type(), 120 | 121 | // error 122 | types.Universe.Lookup("error").Type(), 123 | 124 | // untyped types 125 | types.Typ[types.UntypedBool], 126 | types.Typ[types.UntypedInt], 127 | types.Typ[types.UntypedRune], 128 | types.Typ[types.UntypedFloat], 129 | types.Typ[types.UntypedComplex], 130 | types.Typ[types.UntypedString], 131 | types.Typ[types.UntypedNil], 132 | 133 | // package unsafe 134 | types.Typ[types.UnsafePointer], 135 | 136 | // invalid type 137 | types.Typ[types.Invalid], // only appears in packages with errors 138 | 139 | // used internally by gc; never used by this package or in .a files 140 | anyType{}, 141 | } 142 | predecl = append(predecl, additionalPredeclared()...) 143 | }) 144 | return predecl 145 | } 146 | 147 | type anyType struct{} 148 | 149 | func (t anyType) Underlying() types.Type { return t } 150 | func (t anyType) String() string { return "any" } 151 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gcimporter/exportdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 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 is a copy of $GOROOT/src/go/internal/gcimporter/exportdata.go. 6 | 7 | // This file implements FindExportData. 8 | 9 | package gcimporter 10 | 11 | import ( 12 | "bufio" 13 | "fmt" 14 | "io" 15 | "strconv" 16 | "strings" 17 | ) 18 | 19 | func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) { 20 | // See $GOROOT/include/ar.h. 21 | hdr := make([]byte, 16+12+6+6+8+10+2) 22 | _, err = io.ReadFull(r, hdr) 23 | if err != nil { 24 | return 25 | } 26 | // leave for debugging 27 | if false { 28 | fmt.Printf("header: %s", hdr) 29 | } 30 | s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10])) 31 | length, err := strconv.Atoi(s) 32 | size = int64(length) 33 | if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' { 34 | err = fmt.Errorf("invalid archive header") 35 | return 36 | } 37 | name = strings.TrimSpace(string(hdr[:16])) 38 | return 39 | } 40 | 41 | // FindExportData positions the reader r at the beginning of the 42 | // export data section of an underlying GC-created object/archive 43 | // file by reading from it. The reader must be positioned at the 44 | // start of the file before calling this function. The hdr result 45 | // is the string before the export data, either "$$" or "$$B". 46 | // The size result is the length of the export data in bytes, or -1 if not known. 47 | func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) { 48 | // Read first line to make sure this is an object file. 49 | line, err := r.ReadSlice('\n') 50 | if err != nil { 51 | err = fmt.Errorf("can't find export data (%v)", err) 52 | return 53 | } 54 | 55 | if string(line) == "!\n" { 56 | // Archive file. Scan to __.PKGDEF. 57 | var name string 58 | if name, size, err = readGopackHeader(r); err != nil { 59 | return 60 | } 61 | 62 | // First entry should be __.PKGDEF. 63 | if name != "__.PKGDEF" { 64 | err = fmt.Errorf("go archive is missing __.PKGDEF") 65 | return 66 | } 67 | 68 | // Read first line of __.PKGDEF data, so that line 69 | // is once again the first line of the input. 70 | if line, err = r.ReadSlice('\n'); err != nil { 71 | err = fmt.Errorf("can't find export data (%v)", err) 72 | return 73 | } 74 | size -= int64(len(line)) 75 | } 76 | 77 | // Now at __.PKGDEF in archive or still at beginning of file. 78 | // Either way, line should begin with "go object ". 79 | if !strings.HasPrefix(string(line), "go object ") { 80 | err = fmt.Errorf("not a Go object file") 81 | return 82 | } 83 | 84 | // Skip over object header to export data. 85 | // Begins after first line starting with $$. 86 | for line[0] != '$' { 87 | if line, err = r.ReadSlice('\n'); err != nil { 88 | err = fmt.Errorf("can't find export data (%v)", err) 89 | return 90 | } 91 | size -= int64(len(line)) 92 | } 93 | hdr = string(line) 94 | if size < 0 { 95 | size = -1 96 | } 97 | 98 | return 99 | } 100 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gcimporter/newInterface10.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 | //go:build !go1.11 6 | // +build !go1.11 7 | 8 | package gcimporter 9 | 10 | import "go/types" 11 | 12 | func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { 13 | named := make([]*types.Named, len(embeddeds)) 14 | for i, e := range embeddeds { 15 | var ok bool 16 | named[i], ok = e.(*types.Named) 17 | if !ok { 18 | panic("embedding of non-defined interfaces in interfaces is not supported before Go 1.11") 19 | } 20 | } 21 | return types.NewInterface(methods, named) 22 | } 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gcimporter/newInterface11.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 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 | //go:build go1.11 6 | // +build go1.11 7 | 8 | package gcimporter 9 | 10 | import "go/types" 11 | 12 | func newInterface(methods []*types.Func, embeddeds []types.Type) *types.Interface { 13 | return types.NewInterfaceType(methods, embeddeds) 14 | } 15 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gcimporter/support_go117.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | //go:build !go1.18 6 | // +build !go1.18 7 | 8 | package gcimporter 9 | 10 | import "go/types" 11 | 12 | const iexportVersion = iexportVersionGo1_11 13 | 14 | func additionalPredeclared() []types.Type { 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gcimporter/support_go118.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | //go:build go1.18 6 | // +build go1.18 7 | 8 | package gcimporter 9 | 10 | import "go/types" 11 | 12 | const iexportVersion = iexportVersionGenerics 13 | 14 | // additionalPredeclared returns additional predeclared types in go.1.18. 15 | func additionalPredeclared() []types.Type { 16 | return []types.Type{ 17 | // comparable 18 | types.Universe.Lookup("comparable").Type(), 19 | 20 | // any 21 | types.Universe.Lookup("any").Type(), 22 | } 23 | } 24 | 25 | // See cmd/compile/internal/types.SplitVargenSuffix. 26 | func splitVargenSuffix(name string) (base, suffix string) { 27 | i := len(name) 28 | for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' { 29 | i-- 30 | } 31 | const dot = "·" 32 | if i >= len(dot) && name[i-len(dot):i] == dot { 33 | i -= len(dot) 34 | return name[:i], name[i:] 35 | } 36 | return name, "" 37 | } 38 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gcimporter/unified_no.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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 | //go:build !(go1.18 && goexperiment.unified) 6 | // +build !go1.18 !goexperiment.unified 7 | 8 | package gcimporter 9 | 10 | const unifiedIR = false 11 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gcimporter/unified_yes.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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 | //go:build go1.18 && goexperiment.unified 6 | // +build go1.18,goexperiment.unified 7 | 8 | package gcimporter 9 | 10 | const unifiedIR = true 11 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gcimporter/ureader_no.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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 | //go:build !go1.18 6 | // +build !go1.18 7 | 8 | package gcimporter 9 | 10 | import ( 11 | "fmt" 12 | "go/token" 13 | "go/types" 14 | ) 15 | 16 | func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { 17 | err = fmt.Errorf("go/tools compiled with a Go version earlier than 1.18 cannot read unified IR export data") 18 | return 19 | } 20 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gocommand/vendor.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 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 | package gocommand 6 | 7 | import ( 8 | "bytes" 9 | "context" 10 | "fmt" 11 | "os" 12 | "path/filepath" 13 | "regexp" 14 | "strings" 15 | "time" 16 | 17 | "golang.org/x/mod/semver" 18 | ) 19 | 20 | // ModuleJSON holds information about a module. 21 | type ModuleJSON struct { 22 | Path string // module path 23 | Version string // module version 24 | Versions []string // available module versions (with -versions) 25 | Replace *ModuleJSON // replaced by this module 26 | Time *time.Time // time version was created 27 | Update *ModuleJSON // available update, if any (with -u) 28 | Main bool // is this the main module? 29 | Indirect bool // is this module only an indirect dependency of main module? 30 | Dir string // directory holding files for this module, if any 31 | GoMod string // path to go.mod file used when loading this module, if any 32 | GoVersion string // go version used in module 33 | } 34 | 35 | var modFlagRegexp = regexp.MustCompile(`-mod[ =](\w+)`) 36 | 37 | // VendorEnabled reports whether vendoring is enabled. It takes a *Runner to execute Go commands 38 | // with the supplied context.Context and Invocation. The Invocation can contain pre-defined fields, 39 | // of which only Verb and Args are modified to run the appropriate Go command. 40 | // Inspired by setDefaultBuildMod in modload/init.go 41 | func VendorEnabled(ctx context.Context, inv Invocation, r *Runner) (bool, *ModuleJSON, error) { 42 | mainMod, go114, err := getMainModuleAnd114(ctx, inv, r) 43 | if err != nil { 44 | return false, nil, err 45 | } 46 | 47 | // We check the GOFLAGS to see if there is anything overridden or not. 48 | inv.Verb = "env" 49 | inv.Args = []string{"GOFLAGS"} 50 | stdout, err := r.Run(ctx, inv) 51 | if err != nil { 52 | return false, nil, err 53 | } 54 | goflags := string(bytes.TrimSpace(stdout.Bytes())) 55 | matches := modFlagRegexp.FindStringSubmatch(goflags) 56 | var modFlag string 57 | if len(matches) != 0 { 58 | modFlag = matches[1] 59 | } 60 | // Don't override an explicit '-mod=' argument. 61 | if modFlag == "vendor" { 62 | return true, mainMod, nil 63 | } else if modFlag != "" { 64 | return false, nil, nil 65 | } 66 | if mainMod == nil || !go114 { 67 | return false, nil, nil 68 | } 69 | // Check 1.14's automatic vendor mode. 70 | if fi, err := os.Stat(filepath.Join(mainMod.Dir, "vendor")); err == nil && fi.IsDir() { 71 | if mainMod.GoVersion != "" && semver.Compare("v"+mainMod.GoVersion, "v1.14") >= 0 { 72 | // The Go version is at least 1.14, and a vendor directory exists. 73 | // Set -mod=vendor by default. 74 | return true, mainMod, nil 75 | } 76 | } 77 | return false, nil, nil 78 | } 79 | 80 | // getMainModuleAnd114 gets one of the main modules' information and whether the 81 | // go command in use is 1.14+. This is the information needed to figure out 82 | // if vendoring should be enabled. 83 | func getMainModuleAnd114(ctx context.Context, inv Invocation, r *Runner) (*ModuleJSON, bool, error) { 84 | const format = `{{.Path}} 85 | {{.Dir}} 86 | {{.GoMod}} 87 | {{.GoVersion}} 88 | {{range context.ReleaseTags}}{{if eq . "go1.14"}}{{.}}{{end}}{{end}} 89 | ` 90 | inv.Verb = "list" 91 | inv.Args = []string{"-m", "-f", format} 92 | stdout, err := r.Run(ctx, inv) 93 | if err != nil { 94 | return nil, false, err 95 | } 96 | 97 | lines := strings.Split(stdout.String(), "\n") 98 | if len(lines) < 5 { 99 | return nil, false, fmt.Errorf("unexpected stdout: %q", stdout.String()) 100 | } 101 | mod := &ModuleJSON{ 102 | Path: lines[0], 103 | Dir: lines[1], 104 | GoMod: lines[2], 105 | GoVersion: lines[3], 106 | Main: true, 107 | } 108 | return mod, lines[4] == "go1.14", nil 109 | } 110 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/gocommand/version.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 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 | package gocommand 6 | 7 | import ( 8 | "context" 9 | "fmt" 10 | "regexp" 11 | "strings" 12 | ) 13 | 14 | // GoVersion reports the minor version number of the highest release 15 | // tag built into the go command on the PATH. 16 | // 17 | // Note that this may be higher than the version of the go tool used 18 | // to build this application, and thus the versions of the standard 19 | // go/{scanner,parser,ast,types} packages that are linked into it. 20 | // In that case, callers should either downgrade to the version of 21 | // go used to build the application, or report an error that the 22 | // application is too old to use the go command on the PATH. 23 | func GoVersion(ctx context.Context, inv Invocation, r *Runner) (int, error) { 24 | inv.Verb = "list" 25 | inv.Args = []string{"-e", "-f", `{{context.ReleaseTags}}`, `--`, `unsafe`} 26 | inv.BuildFlags = nil // This is not a build command. 27 | inv.ModFlag = "" 28 | inv.ModFile = "" 29 | inv.Env = append(inv.Env[:len(inv.Env):len(inv.Env)], "GO111MODULE=off") 30 | 31 | stdoutBytes, err := r.Run(ctx, inv) 32 | if err != nil { 33 | return 0, err 34 | } 35 | stdout := stdoutBytes.String() 36 | if len(stdout) < 3 { 37 | return 0, fmt.Errorf("bad ReleaseTags output: %q", stdout) 38 | } 39 | // Split up "[go1.1 go1.15]" and return highest go1.X value. 40 | tags := strings.Fields(stdout[1 : len(stdout)-2]) 41 | for i := len(tags) - 1; i >= 0; i-- { 42 | var version int 43 | if _, err := fmt.Sscanf(tags[i], "go1.%d", &version); err != nil { 44 | continue 45 | } 46 | return version, nil 47 | } 48 | return 0, fmt.Errorf("no parseable ReleaseTags in %v", tags) 49 | } 50 | 51 | // GoVersionOutput returns the complete output of the go version command. 52 | func GoVersionOutput(ctx context.Context, inv Invocation, r *Runner) (string, error) { 53 | inv.Verb = "version" 54 | goVersion, err := r.Run(ctx, inv) 55 | if err != nil { 56 | return "", err 57 | } 58 | return goVersion.String(), nil 59 | } 60 | 61 | // ParseGoVersionOutput extracts the Go version string 62 | // from the output of the "go version" command. 63 | // Given an unrecognized form, it returns an empty string. 64 | func ParseGoVersionOutput(data string) string { 65 | re := regexp.MustCompile(`^go version (go\S+|devel \S+)`) 66 | m := re.FindStringSubmatch(data) 67 | if len(m) != 2 { 68 | return "" // unrecognized version 69 | } 70 | return m[1] 71 | } 72 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/packagesinternal/packages.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 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 | // Package packagesinternal exposes internal-only fields from go/packages. 6 | package packagesinternal 7 | 8 | var GetForTest = func(p interface{}) string { return "" } 9 | var GetDepsErrors = func(p interface{}) []*PackageError { return nil } 10 | 11 | type PackageError struct { 12 | ImportStack []string // shortest path from package named on command line to this one 13 | Pos string // position of error (if present, file:line:col) 14 | Err string // the error itself 15 | } 16 | 17 | var TypecheckCgo int 18 | var DepsErrors int // must be set as a LoadMode to call GetDepsErrors 19 | var ForTest int // must be set as a LoadMode to call GetForTest 20 | 21 | var SetModFlag = func(config interface{}, value string) {} 22 | var SetModFile = func(config interface{}, value string) {} 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/pkgbits/codes.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | package pkgbits 6 | 7 | // A Code is an enum value that can be encoded into bitstreams. 8 | // 9 | // Code types are preferable for enum types, because they allow 10 | // Decoder to detect desyncs. 11 | type Code interface { 12 | // Marker returns the SyncMarker for the Code's dynamic type. 13 | Marker() SyncMarker 14 | 15 | // Value returns the Code's ordinal value. 16 | Value() int 17 | } 18 | 19 | // A CodeVal distinguishes among go/constant.Value encodings. 20 | type CodeVal int 21 | 22 | func (c CodeVal) Marker() SyncMarker { return SyncVal } 23 | func (c CodeVal) Value() int { return int(c) } 24 | 25 | // Note: These values are public and cannot be changed without 26 | // updating the go/types importers. 27 | 28 | const ( 29 | ValBool CodeVal = iota 30 | ValString 31 | ValInt64 32 | ValBigInt 33 | ValBigRat 34 | ValBigFloat 35 | ) 36 | 37 | // A CodeType distinguishes among go/types.Type encodings. 38 | type CodeType int 39 | 40 | func (c CodeType) Marker() SyncMarker { return SyncType } 41 | func (c CodeType) Value() int { return int(c) } 42 | 43 | // Note: These values are public and cannot be changed without 44 | // updating the go/types importers. 45 | 46 | const ( 47 | TypeBasic CodeType = iota 48 | TypeNamed 49 | TypePointer 50 | TypeSlice 51 | TypeArray 52 | TypeChan 53 | TypeMap 54 | TypeSignature 55 | TypeStruct 56 | TypeInterface 57 | TypeUnion 58 | TypeTypeParam 59 | ) 60 | 61 | // A CodeObj distinguishes among go/types.Object encodings. 62 | type CodeObj int 63 | 64 | func (c CodeObj) Marker() SyncMarker { return SyncCodeObj } 65 | func (c CodeObj) Value() int { return int(c) } 66 | 67 | // Note: These values are public and cannot be changed without 68 | // updating the go/types importers. 69 | 70 | const ( 71 | ObjAlias CodeObj = iota 72 | ObjConst 73 | ObjType 74 | ObjFunc 75 | ObjVar 76 | ObjStub 77 | ) 78 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/pkgbits/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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 | // Package pkgbits implements low-level coding abstractions for 6 | // Unified IR's export data format. 7 | // 8 | // At a low-level, a package is a collection of bitstream elements. 9 | // Each element has a "kind" and a dense, non-negative index. 10 | // Elements can be randomly accessed given their kind and index. 11 | // 12 | // Individual elements are sequences of variable-length values (e.g., 13 | // integers, booleans, strings, go/constant values, cross-references 14 | // to other elements). Package pkgbits provides APIs for encoding and 15 | // decoding these low-level values, but the details of mapping 16 | // higher-level Go constructs into elements is left to higher-level 17 | // abstractions. 18 | // 19 | // Elements may cross-reference each other with "relocations." For 20 | // example, an element representing a pointer type has a relocation 21 | // referring to the element type. 22 | // 23 | // Go constructs may be composed as a constellation of multiple 24 | // elements. For example, a declared function may have one element to 25 | // describe the object (e.g., its name, type, position), and a 26 | // separate element to describe its function body. This allows readers 27 | // some flexibility in efficiently seeking or re-reading data (e.g., 28 | // inlining requires re-reading the function body for each inlined 29 | // call, without needing to re-read the object-level details). 30 | // 31 | // This is a copy of internal/pkgbits in the Go implementation. 32 | package pkgbits 33 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/pkgbits/flags.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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 | package pkgbits 6 | 7 | const ( 8 | flagSyncMarkers = 1 << iota // file format contains sync markers 9 | ) 10 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/pkgbits/frames_go1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | //go:build !go1.7 6 | // +build !go1.7 7 | 8 | // TODO(mdempsky): Remove after #44505 is resolved 9 | 10 | package pkgbits 11 | 12 | import "runtime" 13 | 14 | func walkFrames(pcs []uintptr, visit frameVisitor) { 15 | for _, pc := range pcs { 16 | fn := runtime.FuncForPC(pc) 17 | file, line := fn.FileLine(pc) 18 | 19 | visit(file, line, fn.Name(), pc-fn.Entry()) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/pkgbits/frames_go17.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | //go:build go1.7 6 | // +build go1.7 7 | 8 | package pkgbits 9 | 10 | import "runtime" 11 | 12 | // walkFrames calls visit for each call frame represented by pcs. 13 | // 14 | // pcs should be a slice of PCs, as returned by runtime.Callers. 15 | func walkFrames(pcs []uintptr, visit frameVisitor) { 16 | if len(pcs) == 0 { 17 | return 18 | } 19 | 20 | frames := runtime.CallersFrames(pcs) 21 | for { 22 | frame, more := frames.Next() 23 | visit(frame.File, frame.Line, frame.Function, frame.PC-frame.Entry) 24 | if !more { 25 | return 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/pkgbits/reloc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | package pkgbits 6 | 7 | // A RelocKind indicates a particular section within a unified IR export. 8 | type RelocKind int32 9 | 10 | // An Index represents a bitstream element index within a particular 11 | // section. 12 | type Index int32 13 | 14 | // A relocEnt (relocation entry) is an entry in an element's local 15 | // reference table. 16 | // 17 | // TODO(mdempsky): Rename this too. 18 | type RelocEnt struct { 19 | Kind RelocKind 20 | Idx Index 21 | } 22 | 23 | // Reserved indices within the meta relocation section. 24 | const ( 25 | PublicRootIdx Index = 0 26 | PrivateRootIdx Index = 1 27 | ) 28 | 29 | const ( 30 | RelocString RelocKind = iota 31 | RelocMeta 32 | RelocPosBase 33 | RelocPkg 34 | RelocName 35 | RelocType 36 | RelocObj 37 | RelocObjExt 38 | RelocObjDict 39 | RelocBody 40 | 41 | numRelocs = iota 42 | ) 43 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/pkgbits/support.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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 | package pkgbits 6 | 7 | import "fmt" 8 | 9 | func assert(b bool) { 10 | if !b { 11 | panic("assertion failed") 12 | } 13 | } 14 | 15 | func errorf(format string, args ...interface{}) { 16 | panic(fmt.Errorf(format, args...)) 17 | } 18 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/pkgbits/sync.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | package pkgbits 6 | 7 | import ( 8 | "fmt" 9 | "strings" 10 | ) 11 | 12 | // fmtFrames formats a backtrace for reporting reader/writer desyncs. 13 | func fmtFrames(pcs ...uintptr) []string { 14 | res := make([]string, 0, len(pcs)) 15 | walkFrames(pcs, func(file string, line int, name string, offset uintptr) { 16 | // Trim package from function name. It's just redundant noise. 17 | name = strings.TrimPrefix(name, "cmd/compile/internal/noder.") 18 | 19 | res = append(res, fmt.Sprintf("%s:%v: %s +0x%v", file, line, name, offset)) 20 | }) 21 | return res 22 | } 23 | 24 | type frameVisitor func(file string, line int, name string, offset uintptr) 25 | 26 | // SyncMarker is an enum type that represents markers that may be 27 | // written to export data to ensure the reader and writer stay 28 | // synchronized. 29 | type SyncMarker int 30 | 31 | //go:generate stringer -type=SyncMarker -trimprefix=Sync 32 | 33 | const ( 34 | _ SyncMarker = iota 35 | 36 | // Public markers (known to go/types importers). 37 | 38 | // Low-level coding markers. 39 | SyncEOF 40 | SyncBool 41 | SyncInt64 42 | SyncUint64 43 | SyncString 44 | SyncValue 45 | SyncVal 46 | SyncRelocs 47 | SyncReloc 48 | SyncUseReloc 49 | 50 | // Higher-level object and type markers. 51 | SyncPublic 52 | SyncPos 53 | SyncPosBase 54 | SyncObject 55 | SyncObject1 56 | SyncPkg 57 | SyncPkgDef 58 | SyncMethod 59 | SyncType 60 | SyncTypeIdx 61 | SyncTypeParamNames 62 | SyncSignature 63 | SyncParams 64 | SyncParam 65 | SyncCodeObj 66 | SyncSym 67 | SyncLocalIdent 68 | SyncSelector 69 | 70 | // Private markers (only known to cmd/compile). 71 | SyncPrivate 72 | 73 | SyncFuncExt 74 | SyncVarExt 75 | SyncTypeExt 76 | SyncPragma 77 | 78 | SyncExprList 79 | SyncExprs 80 | SyncExpr 81 | SyncExprType 82 | SyncAssign 83 | SyncOp 84 | SyncFuncLit 85 | SyncCompLit 86 | 87 | SyncDecl 88 | SyncFuncBody 89 | SyncOpenScope 90 | SyncCloseScope 91 | SyncCloseAnotherScope 92 | SyncDeclNames 93 | SyncDeclName 94 | 95 | SyncStmts 96 | SyncBlockStmt 97 | SyncIfStmt 98 | SyncForStmt 99 | SyncSwitchStmt 100 | SyncRangeStmt 101 | SyncCaseClause 102 | SyncCommClause 103 | SyncSelectStmt 104 | SyncDecls 105 | SyncLabeledStmt 106 | SyncUseObjLocal 107 | SyncAddLocal 108 | SyncLinkname 109 | SyncStmt1 110 | SyncStmtsEnd 111 | SyncLabel 112 | SyncOptLabel 113 | ) 114 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/pkgbits/syncmarker_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=SyncMarker -trimprefix=Sync"; DO NOT EDIT. 2 | 3 | package pkgbits 4 | 5 | import "strconv" 6 | 7 | func _() { 8 | // An "invalid array index" compiler error signifies that the constant values have changed. 9 | // Re-run the stringer command to generate them again. 10 | var x [1]struct{} 11 | _ = x[SyncEOF-1] 12 | _ = x[SyncBool-2] 13 | _ = x[SyncInt64-3] 14 | _ = x[SyncUint64-4] 15 | _ = x[SyncString-5] 16 | _ = x[SyncValue-6] 17 | _ = x[SyncVal-7] 18 | _ = x[SyncRelocs-8] 19 | _ = x[SyncReloc-9] 20 | _ = x[SyncUseReloc-10] 21 | _ = x[SyncPublic-11] 22 | _ = x[SyncPos-12] 23 | _ = x[SyncPosBase-13] 24 | _ = x[SyncObject-14] 25 | _ = x[SyncObject1-15] 26 | _ = x[SyncPkg-16] 27 | _ = x[SyncPkgDef-17] 28 | _ = x[SyncMethod-18] 29 | _ = x[SyncType-19] 30 | _ = x[SyncTypeIdx-20] 31 | _ = x[SyncTypeParamNames-21] 32 | _ = x[SyncSignature-22] 33 | _ = x[SyncParams-23] 34 | _ = x[SyncParam-24] 35 | _ = x[SyncCodeObj-25] 36 | _ = x[SyncSym-26] 37 | _ = x[SyncLocalIdent-27] 38 | _ = x[SyncSelector-28] 39 | _ = x[SyncPrivate-29] 40 | _ = x[SyncFuncExt-30] 41 | _ = x[SyncVarExt-31] 42 | _ = x[SyncTypeExt-32] 43 | _ = x[SyncPragma-33] 44 | _ = x[SyncExprList-34] 45 | _ = x[SyncExprs-35] 46 | _ = x[SyncExpr-36] 47 | _ = x[SyncExprType-37] 48 | _ = x[SyncAssign-38] 49 | _ = x[SyncOp-39] 50 | _ = x[SyncFuncLit-40] 51 | _ = x[SyncCompLit-41] 52 | _ = x[SyncDecl-42] 53 | _ = x[SyncFuncBody-43] 54 | _ = x[SyncOpenScope-44] 55 | _ = x[SyncCloseScope-45] 56 | _ = x[SyncCloseAnotherScope-46] 57 | _ = x[SyncDeclNames-47] 58 | _ = x[SyncDeclName-48] 59 | _ = x[SyncStmts-49] 60 | _ = x[SyncBlockStmt-50] 61 | _ = x[SyncIfStmt-51] 62 | _ = x[SyncForStmt-52] 63 | _ = x[SyncSwitchStmt-53] 64 | _ = x[SyncRangeStmt-54] 65 | _ = x[SyncCaseClause-55] 66 | _ = x[SyncCommClause-56] 67 | _ = x[SyncSelectStmt-57] 68 | _ = x[SyncDecls-58] 69 | _ = x[SyncLabeledStmt-59] 70 | _ = x[SyncUseObjLocal-60] 71 | _ = x[SyncAddLocal-61] 72 | _ = x[SyncLinkname-62] 73 | _ = x[SyncStmt1-63] 74 | _ = x[SyncStmtsEnd-64] 75 | _ = x[SyncLabel-65] 76 | _ = x[SyncOptLabel-66] 77 | } 78 | 79 | const _SyncMarker_name = "EOFBoolInt64Uint64StringValueValRelocsRelocUseRelocPublicPosPosBaseObjectObject1PkgPkgDefMethodTypeTypeIdxTypeParamNamesSignatureParamsParamCodeObjSymLocalIdentSelectorPrivateFuncExtVarExtTypeExtPragmaExprListExprsExprExprTypeAssignOpFuncLitCompLitDeclFuncBodyOpenScopeCloseScopeCloseAnotherScopeDeclNamesDeclNameStmtsBlockStmtIfStmtForStmtSwitchStmtRangeStmtCaseClauseCommClauseSelectStmtDeclsLabeledStmtUseObjLocalAddLocalLinknameStmt1StmtsEndLabelOptLabel" 80 | 81 | var _SyncMarker_index = [...]uint16{0, 3, 7, 12, 18, 24, 29, 32, 38, 43, 51, 57, 60, 67, 73, 80, 83, 89, 95, 99, 106, 120, 129, 135, 140, 147, 150, 160, 168, 175, 182, 188, 195, 201, 209, 214, 218, 226, 232, 234, 241, 248, 252, 260, 269, 279, 296, 305, 313, 318, 327, 333, 340, 350, 359, 369, 379, 389, 394, 405, 416, 424, 432, 437, 445, 450, 458} 82 | 83 | func (i SyncMarker) String() string { 84 | i -= 1 85 | if i < 0 || i >= SyncMarker(len(_SyncMarker_index)-1) { 86 | return "SyncMarker(" + strconv.FormatInt(int64(i+1), 10) + ")" 87 | } 88 | return _SyncMarker_name[_SyncMarker_index[i]:_SyncMarker_index[i+1]] 89 | } 90 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/tokeninternal/tokeninternal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 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 | // package tokeninternal provides access to some internal features of the token 6 | // package. 7 | package tokeninternal 8 | 9 | import ( 10 | "fmt" 11 | "go/token" 12 | "sort" 13 | "sync" 14 | "unsafe" 15 | ) 16 | 17 | // GetLines returns the table of line-start offsets from a token.File. 18 | func GetLines(file *token.File) []int { 19 | // token.File has a Lines method on Go 1.21 and later. 20 | if file, ok := (interface{})(file).(interface{ Lines() []int }); ok { 21 | return file.Lines() 22 | } 23 | 24 | // This declaration must match that of token.File. 25 | // This creates a risk of dependency skew. 26 | // For now we check that the size of the two 27 | // declarations is the same, on the (fragile) assumption 28 | // that future changes would add fields. 29 | type tokenFile119 struct { 30 | _ string 31 | _ int 32 | _ int 33 | mu sync.Mutex // we're not complete monsters 34 | lines []int 35 | _ []struct{} 36 | } 37 | type tokenFile118 struct { 38 | _ *token.FileSet // deleted in go1.19 39 | tokenFile119 40 | } 41 | 42 | type uP = unsafe.Pointer 43 | switch unsafe.Sizeof(*file) { 44 | case unsafe.Sizeof(tokenFile118{}): 45 | var ptr *tokenFile118 46 | *(*uP)(uP(&ptr)) = uP(file) 47 | ptr.mu.Lock() 48 | defer ptr.mu.Unlock() 49 | return ptr.lines 50 | 51 | case unsafe.Sizeof(tokenFile119{}): 52 | var ptr *tokenFile119 53 | *(*uP)(uP(&ptr)) = uP(file) 54 | ptr.mu.Lock() 55 | defer ptr.mu.Unlock() 56 | return ptr.lines 57 | 58 | default: 59 | panic("unexpected token.File size") 60 | } 61 | } 62 | 63 | // AddExistingFiles adds the specified files to the FileSet if they 64 | // are not already present. It panics if any pair of files in the 65 | // resulting FileSet would overlap. 66 | func AddExistingFiles(fset *token.FileSet, files []*token.File) { 67 | // Punch through the FileSet encapsulation. 68 | type tokenFileSet struct { 69 | // This type remained essentially consistent from go1.16 to go1.21. 70 | mutex sync.RWMutex 71 | base int 72 | files []*token.File 73 | _ *token.File // changed to atomic.Pointer[token.File] in go1.19 74 | } 75 | 76 | // If the size of token.FileSet changes, this will fail to compile. 77 | const delta = int64(unsafe.Sizeof(tokenFileSet{})) - int64(unsafe.Sizeof(token.FileSet{})) 78 | var _ [-delta * delta]int 79 | 80 | type uP = unsafe.Pointer 81 | var ptr *tokenFileSet 82 | *(*uP)(uP(&ptr)) = uP(fset) 83 | ptr.mutex.Lock() 84 | defer ptr.mutex.Unlock() 85 | 86 | // Merge and sort. 87 | newFiles := append(ptr.files, files...) 88 | sort.Slice(newFiles, func(i, j int) bool { 89 | return newFiles[i].Base() < newFiles[j].Base() 90 | }) 91 | 92 | // Reject overlapping files. 93 | // Discard adjacent identical files. 94 | out := newFiles[:0] 95 | for i, file := range newFiles { 96 | if i > 0 { 97 | prev := newFiles[i-1] 98 | if file == prev { 99 | continue 100 | } 101 | if prev.Base()+prev.Size()+1 > file.Base() { 102 | panic(fmt.Sprintf("file %s (%d-%d) overlaps with file %s (%d-%d)", 103 | prev.Name(), prev.Base(), prev.Base()+prev.Size(), 104 | file.Name(), file.Base(), file.Base()+file.Size())) 105 | } 106 | } 107 | out = append(out, file) 108 | } 109 | newFiles = out 110 | 111 | ptr.files = newFiles 112 | 113 | // Advance FileSet.Base(). 114 | if len(newFiles) > 0 { 115 | last := newFiles[len(newFiles)-1] 116 | newBase := last.Base() + last.Size() + 1 117 | if ptr.base < newBase { 118 | ptr.base = newBase 119 | } 120 | } 121 | } 122 | 123 | // FileSetFor returns a new FileSet containing a sequence of new Files with 124 | // the same base, size, and line as the input files, for use in APIs that 125 | // require a FileSet. 126 | // 127 | // Precondition: the input files must be non-overlapping, and sorted in order 128 | // of their Base. 129 | func FileSetFor(files ...*token.File) *token.FileSet { 130 | fset := token.NewFileSet() 131 | for _, f := range files { 132 | f2 := fset.AddFile(f.Name(), f.Base(), f.Size()) 133 | lines := GetLines(f) 134 | f2.SetLines(lines) 135 | } 136 | return fset 137 | } 138 | 139 | // CloneFileSet creates a new FileSet holding all files in fset. It does not 140 | // create copies of the token.Files in fset: they are added to the resulting 141 | // FileSet unmodified. 142 | func CloneFileSet(fset *token.FileSet) *token.FileSet { 143 | var files []*token.File 144 | fset.Iterate(func(f *token.File) bool { 145 | files = append(files, f) 146 | return true 147 | }) 148 | newFileSet := token.NewFileSet() 149 | AddExistingFiles(newFileSet, files) 150 | return newFileSet 151 | } 152 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/typeparams/common.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | // Package typeparams contains common utilities for writing tools that interact 6 | // with generic Go code, as introduced with Go 1.18. 7 | // 8 | // Many of the types and functions in this package are proxies for the new APIs 9 | // introduced in the standard library with Go 1.18. For example, the 10 | // typeparams.Union type is an alias for go/types.Union, and the ForTypeSpec 11 | // function returns the value of the go/ast.TypeSpec.TypeParams field. At Go 12 | // versions older than 1.18 these helpers are implemented as stubs, allowing 13 | // users of this package to write code that handles generic constructs inline, 14 | // even if the Go version being used to compile does not support generics. 15 | // 16 | // Additionally, this package contains common utilities for working with the 17 | // new generic constructs, to supplement the standard library APIs. Notably, 18 | // the StructuralTerms API computes a minimal representation of the structural 19 | // restrictions on a type parameter. 20 | // 21 | // An external version of these APIs is available in the 22 | // golang.org/x/exp/typeparams module. 23 | package typeparams 24 | 25 | import ( 26 | "fmt" 27 | "go/ast" 28 | "go/token" 29 | "go/types" 30 | ) 31 | 32 | // UnpackIndexExpr extracts data from AST nodes that represent index 33 | // expressions. 34 | // 35 | // For an ast.IndexExpr, the resulting indices slice will contain exactly one 36 | // index expression. For an ast.IndexListExpr (go1.18+), it may have a variable 37 | // number of index expressions. 38 | // 39 | // For nodes that don't represent index expressions, the first return value of 40 | // UnpackIndexExpr will be nil. 41 | func UnpackIndexExpr(n ast.Node) (x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) { 42 | switch e := n.(type) { 43 | case *ast.IndexExpr: 44 | return e.X, e.Lbrack, []ast.Expr{e.Index}, e.Rbrack 45 | case *ast.IndexListExpr: 46 | return e.X, e.Lbrack, e.Indices, e.Rbrack 47 | } 48 | return nil, token.NoPos, nil, token.NoPos 49 | } 50 | 51 | // PackIndexExpr returns an *ast.IndexExpr or *ast.IndexListExpr, depending on 52 | // the cardinality of indices. Calling PackIndexExpr with len(indices) == 0 53 | // will panic. 54 | func PackIndexExpr(x ast.Expr, lbrack token.Pos, indices []ast.Expr, rbrack token.Pos) ast.Expr { 55 | switch len(indices) { 56 | case 0: 57 | panic("empty indices") 58 | case 1: 59 | return &ast.IndexExpr{ 60 | X: x, 61 | Lbrack: lbrack, 62 | Index: indices[0], 63 | Rbrack: rbrack, 64 | } 65 | default: 66 | return &ast.IndexListExpr{ 67 | X: x, 68 | Lbrack: lbrack, 69 | Indices: indices, 70 | Rbrack: rbrack, 71 | } 72 | } 73 | } 74 | 75 | // IsTypeParam reports whether t is a type parameter. 76 | func IsTypeParam(t types.Type) bool { 77 | _, ok := t.(*types.TypeParam) 78 | return ok 79 | } 80 | 81 | // OriginMethod returns the origin method associated with the method fn. 82 | // For methods on a non-generic receiver base type, this is just 83 | // fn. However, for methods with a generic receiver, OriginMethod returns the 84 | // corresponding method in the method set of the origin type. 85 | // 86 | // As a special case, if fn is not a method (has no receiver), OriginMethod 87 | // returns fn. 88 | func OriginMethod(fn *types.Func) *types.Func { 89 | recv := fn.Type().(*types.Signature).Recv() 90 | if recv == nil { 91 | return fn 92 | } 93 | base := recv.Type() 94 | p, isPtr := base.(*types.Pointer) 95 | if isPtr { 96 | base = p.Elem() 97 | } 98 | named, isNamed := base.(*types.Named) 99 | if !isNamed { 100 | // Receiver is a *types.Interface. 101 | return fn 102 | } 103 | if named.TypeParams().Len() == 0 { 104 | // Receiver base has no type parameters, so we can avoid the lookup below. 105 | return fn 106 | } 107 | orig := named.Origin() 108 | gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name()) 109 | 110 | // This is a fix for a gopls crash (#60628) due to a go/types bug (#60634). In: 111 | // package p 112 | // type T *int 113 | // func (*T) f() {} 114 | // LookupFieldOrMethod(T, true, p, f)=nil, but NewMethodSet(*T)={(*T).f}. 115 | // Here we make them consistent by force. 116 | // (The go/types bug is general, but this workaround is reached only 117 | // for generic T thanks to the early return above.) 118 | if gfn == nil { 119 | mset := types.NewMethodSet(types.NewPointer(orig)) 120 | for i := 0; i < mset.Len(); i++ { 121 | m := mset.At(i) 122 | if m.Obj().Id() == fn.Id() { 123 | gfn = m.Obj() 124 | break 125 | } 126 | } 127 | } 128 | 129 | // In golang/go#61196, we observe another crash, this time inexplicable. 130 | if gfn == nil { 131 | panic(fmt.Sprintf("missing origin method for %s.%s; named == origin: %t, named.NumMethods(): %d, origin.NumMethods(): %d", named, fn, named == orig, named.NumMethods(), orig.NumMethods())) 132 | } 133 | 134 | return gfn.(*types.Func) 135 | } 136 | 137 | // GenericAssignableTo is a generalization of types.AssignableTo that 138 | // implements the following rule for uninstantiated generic types: 139 | // 140 | // If V and T are generic named types, then V is considered assignable to T if, 141 | // for every possible instantation of V[A_1, ..., A_N], the instantiation 142 | // T[A_1, ..., A_N] is valid and V[A_1, ..., A_N] implements T[A_1, ..., A_N]. 143 | // 144 | // If T has structural constraints, they must be satisfied by V. 145 | // 146 | // For example, consider the following type declarations: 147 | // 148 | // type Interface[T any] interface { 149 | // Accept(T) 150 | // } 151 | // 152 | // type Container[T any] struct { 153 | // Element T 154 | // } 155 | // 156 | // func (c Container[T]) Accept(t T) { c.Element = t } 157 | // 158 | // In this case, GenericAssignableTo reports that instantiations of Container 159 | // are assignable to the corresponding instantiation of Interface. 160 | func GenericAssignableTo(ctxt *types.Context, V, T types.Type) bool { 161 | // If V and T are not both named, or do not have matching non-empty type 162 | // parameter lists, fall back on types.AssignableTo. 163 | 164 | VN, Vnamed := V.(*types.Named) 165 | TN, Tnamed := T.(*types.Named) 166 | if !Vnamed || !Tnamed { 167 | return types.AssignableTo(V, T) 168 | } 169 | 170 | vtparams := VN.TypeParams() 171 | ttparams := TN.TypeParams() 172 | if vtparams.Len() == 0 || vtparams.Len() != ttparams.Len() || VN.TypeArgs().Len() != 0 || TN.TypeArgs().Len() != 0 { 173 | return types.AssignableTo(V, T) 174 | } 175 | 176 | // V and T have the same (non-zero) number of type params. Instantiate both 177 | // with the type parameters of V. This must always succeed for V, and will 178 | // succeed for T if and only if the type set of each type parameter of V is a 179 | // subset of the type set of the corresponding type parameter of T, meaning 180 | // that every instantiation of V corresponds to a valid instantiation of T. 181 | 182 | // Minor optimization: ensure we share a context across the two 183 | // instantiations below. 184 | if ctxt == nil { 185 | ctxt = types.NewContext() 186 | } 187 | 188 | var targs []types.Type 189 | for i := 0; i < vtparams.Len(); i++ { 190 | targs = append(targs, vtparams.At(i)) 191 | } 192 | 193 | vinst, err := types.Instantiate(ctxt, V, targs, true) 194 | if err != nil { 195 | panic("type parameters should satisfy their own constraints") 196 | } 197 | 198 | tinst, err := types.Instantiate(ctxt, T, targs, true) 199 | if err != nil { 200 | return false 201 | } 202 | 203 | return types.AssignableTo(vinst, tinst) 204 | } 205 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/typeparams/coretype.go: -------------------------------------------------------------------------------- 1 | // Copyright 2022 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 | package typeparams 6 | 7 | import ( 8 | "go/types" 9 | ) 10 | 11 | // CoreType returns the core type of T or nil if T does not have a core type. 12 | // 13 | // See https://go.dev/ref/spec#Core_types for the definition of a core type. 14 | func CoreType(T types.Type) types.Type { 15 | U := T.Underlying() 16 | if _, ok := U.(*types.Interface); !ok { 17 | return U // for non-interface types, 18 | } 19 | 20 | terms, err := _NormalTerms(U) 21 | if len(terms) == 0 || err != nil { 22 | // len(terms) -> empty type set of interface. 23 | // err != nil => U is invalid, exceeds complexity bounds, or has an empty type set. 24 | return nil // no core type. 25 | } 26 | 27 | U = terms[0].Type().Underlying() 28 | var identical int // i in [0,identical) => Identical(U, terms[i].Type().Underlying()) 29 | for identical = 1; identical < len(terms); identical++ { 30 | if !types.Identical(U, terms[identical].Type().Underlying()) { 31 | break 32 | } 33 | } 34 | 35 | if identical == len(terms) { 36 | // https://go.dev/ref/spec#Core_types 37 | // "There is a single type U which is the underlying type of all types in the type set of T" 38 | return U 39 | } 40 | ch, ok := U.(*types.Chan) 41 | if !ok { 42 | return nil // no core type as identical < len(terms) and U is not a channel. 43 | } 44 | // https://go.dev/ref/spec#Core_types 45 | // "the type chan E if T contains only bidirectional channels, or the type chan<- E or 46 | // <-chan E depending on the direction of the directional channels present." 47 | for chans := identical; chans < len(terms); chans++ { 48 | curr, ok := terms[chans].Type().Underlying().(*types.Chan) 49 | if !ok { 50 | return nil 51 | } 52 | if !types.Identical(ch.Elem(), curr.Elem()) { 53 | return nil // channel elements are not identical. 54 | } 55 | if ch.Dir() == types.SendRecv { 56 | // ch is bidirectional. We can safely always use curr's direction. 57 | ch = curr 58 | } else if curr.Dir() != types.SendRecv && ch.Dir() != curr.Dir() { 59 | // ch and curr are not bidirectional and not the same direction. 60 | return nil 61 | } 62 | } 63 | return ch 64 | } 65 | 66 | // _NormalTerms returns a slice of terms representing the normalized structural 67 | // type restrictions of a type, if any. 68 | // 69 | // For all types other than *types.TypeParam, *types.Interface, and 70 | // *types.Union, this is just a single term with Tilde() == false and 71 | // Type() == typ. For *types.TypeParam, *types.Interface, and *types.Union, see 72 | // below. 73 | // 74 | // Structural type restrictions of a type parameter are created via 75 | // non-interface types embedded in its constraint interface (directly, or via a 76 | // chain of interface embeddings). For example, in the declaration type 77 | // T[P interface{~int; m()}] int the structural restriction of the type 78 | // parameter P is ~int. 79 | // 80 | // With interface embedding and unions, the specification of structural type 81 | // restrictions may be arbitrarily complex. For example, consider the 82 | // following: 83 | // 84 | // type A interface{ ~string|~[]byte } 85 | // 86 | // type B interface{ int|string } 87 | // 88 | // type C interface { ~string|~int } 89 | // 90 | // type T[P interface{ A|B; C }] int 91 | // 92 | // In this example, the structural type restriction of P is ~string|int: A|B 93 | // expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, 94 | // which when intersected with C (~string|~int) yields ~string|int. 95 | // 96 | // _NormalTerms computes these expansions and reductions, producing a 97 | // "normalized" form of the embeddings. A structural restriction is normalized 98 | // if it is a single union containing no interface terms, and is minimal in the 99 | // sense that removing any term changes the set of types satisfying the 100 | // constraint. It is left as a proof for the reader that, modulo sorting, there 101 | // is exactly one such normalized form. 102 | // 103 | // Because the minimal representation always takes this form, _NormalTerms 104 | // returns a slice of tilde terms corresponding to the terms of the union in 105 | // the normalized structural restriction. An error is returned if the type is 106 | // invalid, exceeds complexity bounds, or has an empty type set. In the latter 107 | // case, _NormalTerms returns ErrEmptyTypeSet. 108 | // 109 | // _NormalTerms makes no guarantees about the order of terms, except that it 110 | // is deterministic. 111 | func _NormalTerms(typ types.Type) ([]*types.Term, error) { 112 | switch typ := typ.(type) { 113 | case *types.TypeParam: 114 | return StructuralTerms(typ) 115 | case *types.Union: 116 | return UnionTermSet(typ) 117 | case *types.Interface: 118 | return InterfaceTermSet(typ) 119 | default: 120 | return []*types.Term{types.NewTerm(false, typ)}, nil 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/typeparams/normalize.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | package typeparams 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "go/types" 11 | "os" 12 | "strings" 13 | ) 14 | 15 | //go:generate go run copytermlist.go 16 | 17 | const debug = false 18 | 19 | var ErrEmptyTypeSet = errors.New("empty type set") 20 | 21 | // StructuralTerms returns a slice of terms representing the normalized 22 | // structural type restrictions of a type parameter, if any. 23 | // 24 | // Structural type restrictions of a type parameter are created via 25 | // non-interface types embedded in its constraint interface (directly, or via a 26 | // chain of interface embeddings). For example, in the declaration 27 | // 28 | // type T[P interface{~int; m()}] int 29 | // 30 | // the structural restriction of the type parameter P is ~int. 31 | // 32 | // With interface embedding and unions, the specification of structural type 33 | // restrictions may be arbitrarily complex. For example, consider the 34 | // following: 35 | // 36 | // type A interface{ ~string|~[]byte } 37 | // 38 | // type B interface{ int|string } 39 | // 40 | // type C interface { ~string|~int } 41 | // 42 | // type T[P interface{ A|B; C }] int 43 | // 44 | // In this example, the structural type restriction of P is ~string|int: A|B 45 | // expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, 46 | // which when intersected with C (~string|~int) yields ~string|int. 47 | // 48 | // StructuralTerms computes these expansions and reductions, producing a 49 | // "normalized" form of the embeddings. A structural restriction is normalized 50 | // if it is a single union containing no interface terms, and is minimal in the 51 | // sense that removing any term changes the set of types satisfying the 52 | // constraint. It is left as a proof for the reader that, modulo sorting, there 53 | // is exactly one such normalized form. 54 | // 55 | // Because the minimal representation always takes this form, StructuralTerms 56 | // returns a slice of tilde terms corresponding to the terms of the union in 57 | // the normalized structural restriction. An error is returned if the 58 | // constraint interface is invalid, exceeds complexity bounds, or has an empty 59 | // type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. 60 | // 61 | // StructuralTerms makes no guarantees about the order of terms, except that it 62 | // is deterministic. 63 | func StructuralTerms(tparam *types.TypeParam) ([]*types.Term, error) { 64 | constraint := tparam.Constraint() 65 | if constraint == nil { 66 | return nil, fmt.Errorf("%s has nil constraint", tparam) 67 | } 68 | iface, _ := constraint.Underlying().(*types.Interface) 69 | if iface == nil { 70 | return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) 71 | } 72 | return InterfaceTermSet(iface) 73 | } 74 | 75 | // InterfaceTermSet computes the normalized terms for a constraint interface, 76 | // returning an error if the term set cannot be computed or is empty. In the 77 | // latter case, the error will be ErrEmptyTypeSet. 78 | // 79 | // See the documentation of StructuralTerms for more information on 80 | // normalization. 81 | func InterfaceTermSet(iface *types.Interface) ([]*types.Term, error) { 82 | return computeTermSet(iface) 83 | } 84 | 85 | // UnionTermSet computes the normalized terms for a union, returning an error 86 | // if the term set cannot be computed or is empty. In the latter case, the 87 | // error will be ErrEmptyTypeSet. 88 | // 89 | // See the documentation of StructuralTerms for more information on 90 | // normalization. 91 | func UnionTermSet(union *types.Union) ([]*types.Term, error) { 92 | return computeTermSet(union) 93 | } 94 | 95 | func computeTermSet(typ types.Type) ([]*types.Term, error) { 96 | tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) 97 | if err != nil { 98 | return nil, err 99 | } 100 | if tset.terms.isEmpty() { 101 | return nil, ErrEmptyTypeSet 102 | } 103 | if tset.terms.isAll() { 104 | return nil, nil 105 | } 106 | var terms []*types.Term 107 | for _, term := range tset.terms { 108 | terms = append(terms, types.NewTerm(term.tilde, term.typ)) 109 | } 110 | return terms, nil 111 | } 112 | 113 | // A termSet holds the normalized set of terms for a given type. 114 | // 115 | // The name termSet is intentionally distinct from 'type set': a type set is 116 | // all types that implement a type (and includes method restrictions), whereas 117 | // a term set just represents the structural restrictions on a type. 118 | type termSet struct { 119 | complete bool 120 | terms termlist 121 | } 122 | 123 | func indentf(depth int, format string, args ...interface{}) { 124 | fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) 125 | } 126 | 127 | func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { 128 | if t == nil { 129 | panic("nil type") 130 | } 131 | 132 | if debug { 133 | indentf(depth, "%s", t.String()) 134 | defer func() { 135 | if err != nil { 136 | indentf(depth, "=> %s", err) 137 | } else { 138 | indentf(depth, "=> %s", res.terms.String()) 139 | } 140 | }() 141 | } 142 | 143 | const maxTermCount = 100 144 | if tset, ok := seen[t]; ok { 145 | if !tset.complete { 146 | return nil, fmt.Errorf("cycle detected in the declaration of %s", t) 147 | } 148 | return tset, nil 149 | } 150 | 151 | // Mark the current type as seen to avoid infinite recursion. 152 | tset := new(termSet) 153 | defer func() { 154 | tset.complete = true 155 | }() 156 | seen[t] = tset 157 | 158 | switch u := t.Underlying().(type) { 159 | case *types.Interface: 160 | // The term set of an interface is the intersection of the term sets of its 161 | // embedded types. 162 | tset.terms = allTermlist 163 | for i := 0; i < u.NumEmbeddeds(); i++ { 164 | embedded := u.EmbeddedType(i) 165 | if _, ok := embedded.Underlying().(*types.TypeParam); ok { 166 | return nil, fmt.Errorf("invalid embedded type %T", embedded) 167 | } 168 | tset2, err := computeTermSetInternal(embedded, seen, depth+1) 169 | if err != nil { 170 | return nil, err 171 | } 172 | tset.terms = tset.terms.intersect(tset2.terms) 173 | } 174 | case *types.Union: 175 | // The term set of a union is the union of term sets of its terms. 176 | tset.terms = nil 177 | for i := 0; i < u.Len(); i++ { 178 | t := u.Term(i) 179 | var terms termlist 180 | switch t.Type().Underlying().(type) { 181 | case *types.Interface: 182 | tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) 183 | if err != nil { 184 | return nil, err 185 | } 186 | terms = tset2.terms 187 | case *types.TypeParam, *types.Union: 188 | // A stand-alone type parameter or union is not permitted as union 189 | // term. 190 | return nil, fmt.Errorf("invalid union term %T", t) 191 | default: 192 | if t.Type() == types.Typ[types.Invalid] { 193 | continue 194 | } 195 | terms = termlist{{t.Tilde(), t.Type()}} 196 | } 197 | tset.terms = tset.terms.union(terms) 198 | if len(tset.terms) > maxTermCount { 199 | return nil, fmt.Errorf("exceeded max term count %d", maxTermCount) 200 | } 201 | } 202 | case *types.TypeParam: 203 | panic("unreachable") 204 | default: 205 | // For all other types, the term set is just a single non-tilde term 206 | // holding the type itself. 207 | if u != types.Typ[types.Invalid] { 208 | tset.terms = termlist{{false, t}} 209 | } 210 | } 211 | return tset, nil 212 | } 213 | 214 | // under is a facade for the go/types internal function of the same name. It is 215 | // used by typeterm.go. 216 | func under(t types.Type) types.Type { 217 | return t.Underlying() 218 | } 219 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/typeparams/termlist.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | // Code generated by copytermlist.go DO NOT EDIT. 6 | 7 | package typeparams 8 | 9 | import ( 10 | "bytes" 11 | "go/types" 12 | ) 13 | 14 | // A termlist represents the type set represented by the union 15 | // t1 ∪ y2 ∪ ... tn of the type sets of the terms t1 to tn. 16 | // A termlist is in normal form if all terms are disjoint. 17 | // termlist operations don't require the operands to be in 18 | // normal form. 19 | type termlist []*term 20 | 21 | // allTermlist represents the set of all types. 22 | // It is in normal form. 23 | var allTermlist = termlist{new(term)} 24 | 25 | // String prints the termlist exactly (without normalization). 26 | func (xl termlist) String() string { 27 | if len(xl) == 0 { 28 | return "∅" 29 | } 30 | var buf bytes.Buffer 31 | for i, x := range xl { 32 | if i > 0 { 33 | buf.WriteString(" | ") 34 | } 35 | buf.WriteString(x.String()) 36 | } 37 | return buf.String() 38 | } 39 | 40 | // isEmpty reports whether the termlist xl represents the empty set of types. 41 | func (xl termlist) isEmpty() bool { 42 | // If there's a non-nil term, the entire list is not empty. 43 | // If the termlist is in normal form, this requires at most 44 | // one iteration. 45 | for _, x := range xl { 46 | if x != nil { 47 | return false 48 | } 49 | } 50 | return true 51 | } 52 | 53 | // isAll reports whether the termlist xl represents the set of all types. 54 | func (xl termlist) isAll() bool { 55 | // If there's a 𝓤 term, the entire list is 𝓤. 56 | // If the termlist is in normal form, this requires at most 57 | // one iteration. 58 | for _, x := range xl { 59 | if x != nil && x.typ == nil { 60 | return true 61 | } 62 | } 63 | return false 64 | } 65 | 66 | // norm returns the normal form of xl. 67 | func (xl termlist) norm() termlist { 68 | // Quadratic algorithm, but good enough for now. 69 | // TODO(gri) fix asymptotic performance 70 | used := make([]bool, len(xl)) 71 | var rl termlist 72 | for i, xi := range xl { 73 | if xi == nil || used[i] { 74 | continue 75 | } 76 | for j := i + 1; j < len(xl); j++ { 77 | xj := xl[j] 78 | if xj == nil || used[j] { 79 | continue 80 | } 81 | if u1, u2 := xi.union(xj); u2 == nil { 82 | // If we encounter a 𝓤 term, the entire list is 𝓤. 83 | // Exit early. 84 | // (Note that this is not just an optimization; 85 | // if we continue, we may end up with a 𝓤 term 86 | // and other terms and the result would not be 87 | // in normal form.) 88 | if u1.typ == nil { 89 | return allTermlist 90 | } 91 | xi = u1 92 | used[j] = true // xj is now unioned into xi - ignore it in future iterations 93 | } 94 | } 95 | rl = append(rl, xi) 96 | } 97 | return rl 98 | } 99 | 100 | // union returns the union xl ∪ yl. 101 | func (xl termlist) union(yl termlist) termlist { 102 | return append(xl, yl...).norm() 103 | } 104 | 105 | // intersect returns the intersection xl ∩ yl. 106 | func (xl termlist) intersect(yl termlist) termlist { 107 | if xl.isEmpty() || yl.isEmpty() { 108 | return nil 109 | } 110 | 111 | // Quadratic algorithm, but good enough for now. 112 | // TODO(gri) fix asymptotic performance 113 | var rl termlist 114 | for _, x := range xl { 115 | for _, y := range yl { 116 | if r := x.intersect(y); r != nil { 117 | rl = append(rl, r) 118 | } 119 | } 120 | } 121 | return rl.norm() 122 | } 123 | 124 | // equal reports whether xl and yl represent the same type set. 125 | func (xl termlist) equal(yl termlist) bool { 126 | // TODO(gri) this should be more efficient 127 | return xl.subsetOf(yl) && yl.subsetOf(xl) 128 | } 129 | 130 | // includes reports whether t ∈ xl. 131 | func (xl termlist) includes(t types.Type) bool { 132 | for _, x := range xl { 133 | if x.includes(t) { 134 | return true 135 | } 136 | } 137 | return false 138 | } 139 | 140 | // supersetOf reports whether y ⊆ xl. 141 | func (xl termlist) supersetOf(y *term) bool { 142 | for _, x := range xl { 143 | if y.subsetOf(x) { 144 | return true 145 | } 146 | } 147 | return false 148 | } 149 | 150 | // subsetOf reports whether xl ⊆ yl. 151 | func (xl termlist) subsetOf(yl termlist) bool { 152 | if yl.isEmpty() { 153 | return xl.isEmpty() 154 | } 155 | 156 | // each term x of xl must be a subset of yl 157 | for _, x := range xl { 158 | if !yl.supersetOf(x) { 159 | return false // x is not a subset yl 160 | } 161 | } 162 | return true 163 | } 164 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/typeparams/typeterm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | // Code generated by copytermlist.go DO NOT EDIT. 6 | 7 | package typeparams 8 | 9 | import "go/types" 10 | 11 | // A term describes elementary type sets: 12 | // 13 | // ∅: (*term)(nil) == ∅ // set of no types (empty set) 14 | // 𝓤: &term{} == 𝓤 // set of all types (𝓤niverse) 15 | // T: &term{false, T} == {T} // set of type T 16 | // ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t 17 | type term struct { 18 | tilde bool // valid if typ != nil 19 | typ types.Type 20 | } 21 | 22 | func (x *term) String() string { 23 | switch { 24 | case x == nil: 25 | return "∅" 26 | case x.typ == nil: 27 | return "𝓤" 28 | case x.tilde: 29 | return "~" + x.typ.String() 30 | default: 31 | return x.typ.String() 32 | } 33 | } 34 | 35 | // equal reports whether x and y represent the same type set. 36 | func (x *term) equal(y *term) bool { 37 | // easy cases 38 | switch { 39 | case x == nil || y == nil: 40 | return x == y 41 | case x.typ == nil || y.typ == nil: 42 | return x.typ == y.typ 43 | } 44 | // ∅ ⊂ x, y ⊂ 𝓤 45 | 46 | return x.tilde == y.tilde && types.Identical(x.typ, y.typ) 47 | } 48 | 49 | // union returns the union x ∪ y: zero, one, or two non-nil terms. 50 | func (x *term) union(y *term) (_, _ *term) { 51 | // easy cases 52 | switch { 53 | case x == nil && y == nil: 54 | return nil, nil // ∅ ∪ ∅ == ∅ 55 | case x == nil: 56 | return y, nil // ∅ ∪ y == y 57 | case y == nil: 58 | return x, nil // x ∪ ∅ == x 59 | case x.typ == nil: 60 | return x, nil // 𝓤 ∪ y == 𝓤 61 | case y.typ == nil: 62 | return y, nil // x ∪ 𝓤 == 𝓤 63 | } 64 | // ∅ ⊂ x, y ⊂ 𝓤 65 | 66 | if x.disjoint(y) { 67 | return x, y // x ∪ y == (x, y) if x ∩ y == ∅ 68 | } 69 | // x.typ == y.typ 70 | 71 | // ~t ∪ ~t == ~t 72 | // ~t ∪ T == ~t 73 | // T ∪ ~t == ~t 74 | // T ∪ T == T 75 | if x.tilde || !y.tilde { 76 | return x, nil 77 | } 78 | return y, nil 79 | } 80 | 81 | // intersect returns the intersection x ∩ y. 82 | func (x *term) intersect(y *term) *term { 83 | // easy cases 84 | switch { 85 | case x == nil || y == nil: 86 | return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ 87 | case x.typ == nil: 88 | return y // 𝓤 ∩ y == y 89 | case y.typ == nil: 90 | return x // x ∩ 𝓤 == x 91 | } 92 | // ∅ ⊂ x, y ⊂ 𝓤 93 | 94 | if x.disjoint(y) { 95 | return nil // x ∩ y == ∅ if x ∩ y == ∅ 96 | } 97 | // x.typ == y.typ 98 | 99 | // ~t ∩ ~t == ~t 100 | // ~t ∩ T == T 101 | // T ∩ ~t == T 102 | // T ∩ T == T 103 | if !x.tilde || y.tilde { 104 | return x 105 | } 106 | return y 107 | } 108 | 109 | // includes reports whether t ∈ x. 110 | func (x *term) includes(t types.Type) bool { 111 | // easy cases 112 | switch { 113 | case x == nil: 114 | return false // t ∈ ∅ == false 115 | case x.typ == nil: 116 | return true // t ∈ 𝓤 == true 117 | } 118 | // ∅ ⊂ x ⊂ 𝓤 119 | 120 | u := t 121 | if x.tilde { 122 | u = under(u) 123 | } 124 | return types.Identical(x.typ, u) 125 | } 126 | 127 | // subsetOf reports whether x ⊆ y. 128 | func (x *term) subsetOf(y *term) bool { 129 | // easy cases 130 | switch { 131 | case x == nil: 132 | return true // ∅ ⊆ y == true 133 | case y == nil: 134 | return false // x ⊆ ∅ == false since x != ∅ 135 | case y.typ == nil: 136 | return true // x ⊆ 𝓤 == true 137 | case x.typ == nil: 138 | return false // 𝓤 ⊆ y == false since y != 𝓤 139 | } 140 | // ∅ ⊂ x, y ⊂ 𝓤 141 | 142 | if x.disjoint(y) { 143 | return false // x ⊆ y == false if x ∩ y == ∅ 144 | } 145 | // x.typ == y.typ 146 | 147 | // ~t ⊆ ~t == true 148 | // ~t ⊆ T == false 149 | // T ⊆ ~t == true 150 | // T ⊆ T == true 151 | return !x.tilde || y.tilde 152 | } 153 | 154 | // disjoint reports whether x ∩ y == ∅. 155 | // x.typ and y.typ must not be nil. 156 | func (x *term) disjoint(y *term) bool { 157 | if debug && (x.typ == nil || y.typ == nil) { 158 | panic("invalid argument(s)") 159 | } 160 | ux := x.typ 161 | if y.tilde { 162 | ux = under(ux) 163 | } 164 | uy := y.typ 165 | if x.tilde { 166 | uy = under(uy) 167 | } 168 | return !types.Identical(ux, uy) 169 | } 170 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/typesinternal/types.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 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 | // Package typesinternal provides access to internal go/types APIs that are not 6 | // yet exported. 7 | package typesinternal 8 | 9 | import ( 10 | "go/token" 11 | "go/types" 12 | "reflect" 13 | "unsafe" 14 | ) 15 | 16 | func SetUsesCgo(conf *types.Config) bool { 17 | v := reflect.ValueOf(conf).Elem() 18 | 19 | f := v.FieldByName("go115UsesCgo") 20 | if !f.IsValid() { 21 | f = v.FieldByName("UsesCgo") 22 | if !f.IsValid() { 23 | return false 24 | } 25 | } 26 | 27 | addr := unsafe.Pointer(f.UnsafeAddr()) 28 | *(*bool)(addr) = true 29 | 30 | return true 31 | } 32 | 33 | // ReadGo116ErrorData extracts additional information from types.Error values 34 | // generated by Go version 1.16 and later: the error code, start position, and 35 | // end position. If all positions are valid, start <= err.Pos <= end. 36 | // 37 | // If the data could not be read, the final result parameter will be false. 38 | func ReadGo116ErrorData(err types.Error) (code ErrorCode, start, end token.Pos, ok bool) { 39 | var data [3]int 40 | // By coincidence all of these fields are ints, which simplifies things. 41 | v := reflect.ValueOf(err) 42 | for i, name := range []string{"go116code", "go116start", "go116end"} { 43 | f := v.FieldByName(name) 44 | if !f.IsValid() { 45 | return 0, 0, 0, false 46 | } 47 | data[i] = int(f.Int()) 48 | } 49 | return ErrorCode(data[0]), token.Pos(data[1]), token.Pos(data[2]), true 50 | } 51 | 52 | var SetGoVersion = func(conf *types.Config, version string) bool { return false } 53 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/typesinternal/types_118.go: -------------------------------------------------------------------------------- 1 | // Copyright 2021 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 | //go:build go1.18 6 | // +build go1.18 7 | 8 | package typesinternal 9 | 10 | import ( 11 | "go/types" 12 | ) 13 | 14 | func init() { 15 | SetGoVersion = func(conf *types.Config, version string) bool { 16 | conf.GoVersion = version 17 | return true 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/versions/gover.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 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 is a fork of internal/gover for use by x/tools until 6 | // go1.21 and earlier are no longer supported by x/tools. 7 | 8 | package versions 9 | 10 | import "strings" 11 | 12 | // A gover is a parsed Go gover: major[.Minor[.Patch]][kind[pre]] 13 | // The numbers are the original decimal strings to avoid integer overflows 14 | // and since there is very little actual math. (Probably overflow doesn't matter in practice, 15 | // but at the time this code was written, there was an existing test that used 16 | // go1.99999999999, which does not fit in an int on 32-bit platforms. 17 | // The "big decimal" representation avoids the problem entirely.) 18 | type gover struct { 19 | major string // decimal 20 | minor string // decimal or "" 21 | patch string // decimal or "" 22 | kind string // "", "alpha", "beta", "rc" 23 | pre string // decimal or "" 24 | } 25 | 26 | // compare returns -1, 0, or +1 depending on whether 27 | // x < y, x == y, or x > y, interpreted as toolchain versions. 28 | // The versions x and y must not begin with a "go" prefix: just "1.21" not "go1.21". 29 | // Malformed versions compare less than well-formed versions and equal to each other. 30 | // The language version "1.21" compares less than the release candidate and eventual releases "1.21rc1" and "1.21.0". 31 | func compare(x, y string) int { 32 | vx := parse(x) 33 | vy := parse(y) 34 | 35 | if c := cmpInt(vx.major, vy.major); c != 0 { 36 | return c 37 | } 38 | if c := cmpInt(vx.minor, vy.minor); c != 0 { 39 | return c 40 | } 41 | if c := cmpInt(vx.patch, vy.patch); c != 0 { 42 | return c 43 | } 44 | if c := strings.Compare(vx.kind, vy.kind); c != 0 { // "" < alpha < beta < rc 45 | return c 46 | } 47 | if c := cmpInt(vx.pre, vy.pre); c != 0 { 48 | return c 49 | } 50 | return 0 51 | } 52 | 53 | // lang returns the Go language version. For example, lang("1.2.3") == "1.2". 54 | func lang(x string) string { 55 | v := parse(x) 56 | if v.minor == "" || v.major == "1" && v.minor == "0" { 57 | return v.major 58 | } 59 | return v.major + "." + v.minor 60 | } 61 | 62 | // isValid reports whether the version x is valid. 63 | func isValid(x string) bool { 64 | return parse(x) != gover{} 65 | } 66 | 67 | // parse parses the Go version string x into a version. 68 | // It returns the zero version if x is malformed. 69 | func parse(x string) gover { 70 | var v gover 71 | 72 | // Parse major version. 73 | var ok bool 74 | v.major, x, ok = cutInt(x) 75 | if !ok { 76 | return gover{} 77 | } 78 | if x == "" { 79 | // Interpret "1" as "1.0.0". 80 | v.minor = "0" 81 | v.patch = "0" 82 | return v 83 | } 84 | 85 | // Parse . before minor version. 86 | if x[0] != '.' { 87 | return gover{} 88 | } 89 | 90 | // Parse minor version. 91 | v.minor, x, ok = cutInt(x[1:]) 92 | if !ok { 93 | return gover{} 94 | } 95 | if x == "" { 96 | // Patch missing is same as "0" for older versions. 97 | // Starting in Go 1.21, patch missing is different from explicit .0. 98 | if cmpInt(v.minor, "21") < 0 { 99 | v.patch = "0" 100 | } 101 | return v 102 | } 103 | 104 | // Parse patch if present. 105 | if x[0] == '.' { 106 | v.patch, x, ok = cutInt(x[1:]) 107 | if !ok || x != "" { 108 | // Note that we are disallowing prereleases (alpha, beta, rc) for patch releases here (x != ""). 109 | // Allowing them would be a bit confusing because we already have: 110 | // 1.21 < 1.21rc1 111 | // But a prerelease of a patch would have the opposite effect: 112 | // 1.21.3rc1 < 1.21.3 113 | // We've never needed them before, so let's not start now. 114 | return gover{} 115 | } 116 | return v 117 | } 118 | 119 | // Parse prerelease. 120 | i := 0 121 | for i < len(x) && (x[i] < '0' || '9' < x[i]) { 122 | if x[i] < 'a' || 'z' < x[i] { 123 | return gover{} 124 | } 125 | i++ 126 | } 127 | if i == 0 { 128 | return gover{} 129 | } 130 | v.kind, x = x[:i], x[i:] 131 | if x == "" { 132 | return v 133 | } 134 | v.pre, x, ok = cutInt(x) 135 | if !ok || x != "" { 136 | return gover{} 137 | } 138 | 139 | return v 140 | } 141 | 142 | // cutInt scans the leading decimal number at the start of x to an integer 143 | // and returns that value and the rest of the string. 144 | func cutInt(x string) (n, rest string, ok bool) { 145 | i := 0 146 | for i < len(x) && '0' <= x[i] && x[i] <= '9' { 147 | i++ 148 | } 149 | if i == 0 || x[0] == '0' && i != 1 { // no digits or unnecessary leading zero 150 | return "", "", false 151 | } 152 | return x[:i], x[i:], true 153 | } 154 | 155 | // cmpInt returns cmp.Compare(x, y) interpreting x and y as decimal numbers. 156 | // (Copied from golang.org/x/mod/semver's compareInt.) 157 | func cmpInt(x, y string) int { 158 | if x == y { 159 | return 0 160 | } 161 | if len(x) < len(y) { 162 | return -1 163 | } 164 | if len(x) > len(y) { 165 | return +1 166 | } 167 | if x < y { 168 | return -1 169 | } else { 170 | return +1 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/versions/types.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 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 | package versions 6 | 7 | import ( 8 | "go/types" 9 | ) 10 | 11 | // GoVersion returns the Go version of the type package. 12 | // It returns zero if no version can be determined. 13 | func GoVersion(pkg *types.Package) string { 14 | // TODO(taking): x/tools can call GoVersion() [from 1.21] after 1.25. 15 | if pkg, ok := any(pkg).(interface{ GoVersion() string }); ok { 16 | return pkg.GoVersion() 17 | } 18 | return "" 19 | } 20 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/versions/types_go121.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 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 | //go:build !go1.22 6 | // +build !go1.22 7 | 8 | package versions 9 | 10 | import ( 11 | "go/ast" 12 | "go/types" 13 | ) 14 | 15 | // FileVersions always reports the a file's Go version as the 16 | // zero version at this Go version. 17 | func FileVersions(info *types.Info, file *ast.File) string { return "" } 18 | 19 | // InitFileVersions is a noop at this Go version. 20 | func InitFileVersions(*types.Info) {} 21 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/versions/types_go122.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 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 | //go:build go1.22 6 | // +build go1.22 7 | 8 | package versions 9 | 10 | import ( 11 | "go/ast" 12 | "go/types" 13 | ) 14 | 15 | // FileVersions maps a file to the file's semantic Go version. 16 | // The reported version is the zero version if a version cannot be determined. 17 | func FileVersions(info *types.Info, file *ast.File) string { 18 | return info.FileVersions[file] 19 | } 20 | 21 | // InitFileVersions initializes info to record Go versions for Go files. 22 | func InitFileVersions(info *types.Info) { 23 | info.FileVersions = make(map[*ast.File]string) 24 | } 25 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/internal/versions/versions.go: -------------------------------------------------------------------------------- 1 | // Copyright 2023 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 | package versions 6 | 7 | // Note: If we use build tags to use go/versions when go >=1.22, 8 | // we run into go.dev/issue/53737. Under some operations users would see an 9 | // import of "go/versions" even if they would not compile the file. 10 | // For example, during `go get -u ./...` (go.dev/issue/64490) we do not try to include 11 | // For this reason, this library just a clone of go/versions for the moment. 12 | 13 | // Lang returns the Go language version for version x. 14 | // If x is not a valid version, Lang returns the empty string. 15 | // For example: 16 | // 17 | // Lang("go1.21rc2") = "go1.21" 18 | // Lang("go1.21.2") = "go1.21" 19 | // Lang("go1.21") = "go1.21" 20 | // Lang("go1") = "go1" 21 | // Lang("bad") = "" 22 | // Lang("1.21") = "" 23 | func Lang(x string) string { 24 | v := lang(stripGo(x)) 25 | if v == "" { 26 | return "" 27 | } 28 | return x[:2+len(v)] // "go"+v without allocation 29 | } 30 | 31 | // Compare returns -1, 0, or +1 depending on whether 32 | // x < y, x == y, or x > y, interpreted as Go versions. 33 | // The versions x and y must begin with a "go" prefix: "go1.21" not "1.21". 34 | // Invalid versions, including the empty string, compare less than 35 | // valid versions and equal to each other. 36 | // The language version "go1.21" compares less than the 37 | // release candidate and eventual releases "go1.21rc1" and "go1.21.0". 38 | // Custom toolchain suffixes are ignored during comparison: 39 | // "go1.21.0" and "go1.21.0-bigcorp" are equal. 40 | func Compare(x, y string) int { return compare(stripGo(x), stripGo(y)) } 41 | 42 | // IsValid reports whether the version x is valid. 43 | func IsValid(x string) bool { return isValid(stripGo(x)) } 44 | 45 | // stripGo converts from a "go1.21" version to a "1.21" version. 46 | // If v does not start with "go", stripGo returns the empty string (a known invalid version). 47 | func stripGo(v string) string { 48 | if len(v) < 2 || v[:2] != "go" { 49 | return "" 50 | } 51 | return v[2:] 52 | } 53 | -------------------------------------------------------------------------------- /vendor/golang.org/x/tools/refactor/importgraph/graph.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 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 | // Package importgraph computes the forward and reverse import 6 | // dependency graphs for all packages in a Go workspace. 7 | package importgraph // import "golang.org/x/tools/refactor/importgraph" 8 | 9 | import ( 10 | "go/build" 11 | "sync" 12 | 13 | "golang.org/x/tools/go/buildutil" 14 | ) 15 | 16 | // A Graph is an import dependency graph, either forward or reverse. 17 | // 18 | // The graph maps each node (a package import path) to the set of its 19 | // successors in the graph. For a forward graph, this is the set of 20 | // imported packages (prerequisites); for a reverse graph, it is the set 21 | // of importing packages (clients). 22 | // 23 | // Graph construction inspects all imports in each package's directory, 24 | // including those in _test.go files, so the resulting graph may be cyclic. 25 | type Graph map[string]map[string]bool 26 | 27 | func (g Graph) addEdge(from, to string) { 28 | edges := g[from] 29 | if edges == nil { 30 | edges = make(map[string]bool) 31 | g[from] = edges 32 | } 33 | edges[to] = true 34 | } 35 | 36 | // Search returns all the nodes of the graph reachable from 37 | // any of the specified roots, by following edges forwards. 38 | // Relationally, this is the reflexive transitive closure. 39 | func (g Graph) Search(roots ...string) map[string]bool { 40 | seen := make(map[string]bool) 41 | var visit func(x string) 42 | visit = func(x string) { 43 | if !seen[x] { 44 | seen[x] = true 45 | for y := range g[x] { 46 | visit(y) 47 | } 48 | } 49 | } 50 | for _, root := range roots { 51 | visit(root) 52 | } 53 | return seen 54 | } 55 | 56 | // Build scans the specified Go workspace and builds the forward and 57 | // reverse import dependency graphs for all its packages. 58 | // It also returns a mapping from canonical import paths to errors for packages 59 | // whose loading was not entirely successful. 60 | // A package may appear in the graph and in the errors mapping. 61 | // All package paths are canonical and may contain "/vendor/". 62 | func Build(ctxt *build.Context) (forward, reverse Graph, errors map[string]error) { 63 | type importEdge struct { 64 | from, to string 65 | } 66 | type pathError struct { 67 | path string 68 | err error 69 | } 70 | 71 | ch := make(chan interface{}) 72 | 73 | go func() { 74 | sema := make(chan int, 20) // I/O concurrency limiting semaphore 75 | var wg sync.WaitGroup 76 | buildutil.ForEachPackage(ctxt, func(path string, err error) { 77 | if err != nil { 78 | ch <- pathError{path, err} 79 | return 80 | } 81 | 82 | wg.Add(1) 83 | go func() { 84 | defer wg.Done() 85 | 86 | sema <- 1 87 | bp, err := ctxt.Import(path, "", 0) 88 | <-sema 89 | 90 | if err != nil { 91 | if _, ok := err.(*build.NoGoError); ok { 92 | // empty directory is not an error 93 | } else { 94 | ch <- pathError{path, err} 95 | } 96 | // Even in error cases, Import usually returns a package. 97 | } 98 | 99 | // absolutize resolves an import path relative 100 | // to the current package bp. 101 | // The absolute form may contain "vendor". 102 | // 103 | // The vendoring feature slows down Build by 3×. 104 | // Here are timings from a 1400 package workspace: 105 | // 1100ms: current code (with vendor check) 106 | // 880ms: with a nonblocking cache around ctxt.IsDir 107 | // 840ms: nonblocking cache with duplicate suppression 108 | // 340ms: original code (no vendor check) 109 | // TODO(adonovan): optimize, somehow. 110 | memo := make(map[string]string) 111 | absolutize := func(path string) string { 112 | canon, ok := memo[path] 113 | if !ok { 114 | sema <- 1 115 | bp2, _ := ctxt.Import(path, bp.Dir, build.FindOnly) 116 | <-sema 117 | 118 | if bp2 != nil { 119 | canon = bp2.ImportPath 120 | } else { 121 | canon = path 122 | } 123 | memo[path] = canon 124 | } 125 | return canon 126 | } 127 | 128 | if bp != nil { 129 | for _, imp := range bp.Imports { 130 | ch <- importEdge{path, absolutize(imp)} 131 | } 132 | for _, imp := range bp.TestImports { 133 | ch <- importEdge{path, absolutize(imp)} 134 | } 135 | for _, imp := range bp.XTestImports { 136 | ch <- importEdge{path, absolutize(imp)} 137 | } 138 | } 139 | 140 | }() 141 | }) 142 | wg.Wait() 143 | close(ch) 144 | }() 145 | 146 | forward = make(Graph) 147 | reverse = make(Graph) 148 | 149 | for e := range ch { 150 | switch e := e.(type) { 151 | case pathError: 152 | if errors == nil { 153 | errors = make(map[string]error) 154 | } 155 | errors[e.path] = e.err 156 | 157 | case importEdge: 158 | if e.to == "C" { 159 | continue // "C" is fake 160 | } 161 | forward.addEdge(e.from, e.to) 162 | reverse.addEdge(e.to, e.from) 163 | } 164 | } 165 | 166 | return forward, reverse, errors 167 | } 168 | -------------------------------------------------------------------------------- /vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/kisielk/gotool v1.0.0 2 | ## explicit 3 | github.com/kisielk/gotool 4 | github.com/kisielk/gotool/internal/load 5 | # golang.org/x/mod v0.15.0 6 | ## explicit; go 1.18 7 | golang.org/x/mod/semver 8 | # golang.org/x/tools v0.17.0 9 | ## explicit; go 1.18 10 | golang.org/x/tools/go/ast/astutil 11 | golang.org/x/tools/go/buildutil 12 | golang.org/x/tools/go/gcexportdata 13 | golang.org/x/tools/go/internal/cgo 14 | golang.org/x/tools/go/internal/packagesdriver 15 | golang.org/x/tools/go/loader 16 | golang.org/x/tools/go/packages 17 | golang.org/x/tools/go/types/objectpath 18 | golang.org/x/tools/internal/event 19 | golang.org/x/tools/internal/event/core 20 | golang.org/x/tools/internal/event/keys 21 | golang.org/x/tools/internal/event/label 22 | golang.org/x/tools/internal/event/tag 23 | golang.org/x/tools/internal/gcimporter 24 | golang.org/x/tools/internal/gocommand 25 | golang.org/x/tools/internal/packagesinternal 26 | golang.org/x/tools/internal/pkgbits 27 | golang.org/x/tools/internal/tokeninternal 28 | golang.org/x/tools/internal/typeparams 29 | golang.org/x/tools/internal/typesinternal 30 | golang.org/x/tools/internal/versions 31 | golang.org/x/tools/refactor/importgraph 32 | --------------------------------------------------------------------------------